< 返回版块

挺肥 发表于 2020-11-19 16:20

代码如下:

let s1 = String::from("hello");
let s2 = "hello";
assert_eq!(s1, s2);

评论区

写评论
作者 挺肥 2020-11-20 10:53

十分感谢,说的太清楚了

--
👇
gwy15: 这个说法是错的,跟 Deref 没有直接的关系,你可以这样写:

// assert macro will print using debug format
#[derive(Debug)]
struct S {
    inner: String,
}

impl S {
    pub fn new(inner: &str) -> Self {
        Self {
            inner: inner.to_owned(),
        }
    }
}

impl std::cmp::PartialEq<&str> for S {
    fn eq(&self, other: &&str) -> bool {
        return self.inner.eq(other);
    }
}

// comment for compile error
impl std::cmp::PartialEq<S> for &str {
    fn eq(&self, _other: &S) -> bool {
        return false;
    }
}

fn main() {
    let s = "hello";
    let string = String::from("hello");
    let fake_string = S::new("hello");
    assert_eq!(string, s);
    assert_eq!(fake_string, s);
    assert_eq!(s, fake_string);
}

这里 S 没有实现任何 deref,但是还是可以通过编译。

assert_eq 宏展开之后是这样的:

        match (&s, &fake_string) {
            (left_val, right_val) => {
                if !(*left_val == *right_val) {
                    {
                        ::std::rt::begin_panic_fmt...

也就是说这里只调用了 lhs == rhs,只要实现了 PartialEq for Lhs 就可以了。 String 的文档里面两种顺序都实现了。

gwy15 2020-11-19 17:15

这个说法是错的,跟 Deref 没有直接的关系,你可以这样写:

// assert macro will print using debug format
#[derive(Debug)]
struct S {
    inner: String,
}

impl S {
    pub fn new(inner: &str) -> Self {
        Self {
            inner: inner.to_owned(),
        }
    }
}

impl std::cmp::PartialEq<&str> for S {
    fn eq(&self, other: &&str) -> bool {
        return self.inner.eq(other);
    }
}

// comment for compile error
impl std::cmp::PartialEq<S> for &str {
    fn eq(&self, _other: &S) -> bool {
        return false;
    }
}

fn main() {
    let s = "hello";
    let string = String::from("hello");
    let fake_string = S::new("hello");
    assert_eq!(string, s);
    assert_eq!(fake_string, s);
    assert_eq!(s, fake_string);
}

这里 S 没有实现任何 deref,但是还是可以通过编译。

assert_eq 宏展开之后是这样的:

        match (&s, &fake_string) {
            (left_val, right_val) => {
                if !(*left_val == *right_val) {
                    {
                        ::std::rt::begin_panic_fmt...

也就是说这里只调用了 lhs == rhs,只要实现了 PartialEq for Lhs 就可以了。 String 的文档里面两种顺序都实现了。

作者 挺肥 2020-11-19 17:03

在 reddit 上面得到了解答:

https://www.reddit.com/r/rust/comments/jwz1ae/why_use_assert_eq_to_compare_string_and_str_will/

1 共 3 条评论, 1 页