在Rust中,两个引用变量如何相等?

8

我有一段代码,其中一个函数存在bug:

fn is_five(x: &i32) -> bool {
    x == 5
}

fn main() {
    assert!(is_five(&5));
    assert!(!is_five(&6));
    println!("Success!");
}

运行时出现错误:

error[E0277]: can't compare `&i32` with `{integer}`
 --> main.rs:2:7
  |
2 |     x == 5
  |       ^^ no implementation for `&i32 == {integer}`
  |
  = help: the trait `std::cmp::PartialEq<{integer}>` is not implemented for `&i32`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.

我通过比较两个值而不是一个地址和一个值的逻辑来解决了这个问题。

fn is_five(x: &i32) -> bool {
    *x == 5
}

然而,我也随意尝试了借用方法,令我惊讶的是,它起作用了。

fn is_five(x: &i32) -> bool {
    x == &5
}

我不理解两个地址是如何相同的?难道 == 操作符有一些特性可以获取两端存储的值吗?


1
你可以使用 std::ptr::eq 来比较指针而不是值,以防万一你需要它。 - Aunmag
1个回答

5
要实现==,必须实现PartialEq。如果您查看此处的文档,则可以看到如果类型A实现了PartialEq<B>,那么&'_ A就实现了PartialEq<&'_ B>。换句话说,如果您能比较值,则可以使用引用进行比较。
同样的推理也适用于其他比较特性:EqPartialOrdOrd,以及可变引用。

3
“如果你可以比较值,那么你也可以比较它们的指针”这句话有点误导人,因为当你写x == &5时,被比较的不是指针本身,而是它们所指向的值。 - user4815162342
1
@user4815162342 是的,你说得对。我应该更清楚地写出“如果你可以比较值,你可以使用指向它们的指针进行比较”。话虽如此,但是说定义值之间的偏序关系意味着在指向这些值的指针上定义了偏序关系并不是错误的。感谢澄清。 - Bromind
2
请注意,您正在比较引用而非指针。比较指针会比较指针本身而不是指向的值 - Jmb
1
@Jmb 感谢您的纠正。对于其他发现区别不清的用户,这里提供更多信息:https://dev59.com/5lIG5IYBdhLWcg3w62UZ - Bromind

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接