比较值和参考值

Dan*_*olf 5 rust

考虑下面的 Rust 函数,它的目的是指示给定的 3 字节字符串是否等于b"foo"

fn is_foo(value: [u8; 3]) -> bool {
    value == b"foo"
}
Run Code Online (Sandbox Code Playgroud)

这不起作用:

错误[E0277]:无法[u8; 3]比较&[u8; 3]

编译器抱怨它无法将某种类型的值与相同类型的引用进行比较。

我发现了两种让平等检查发挥作用的方法:

  • 首先将值转换为 ref:&value == b"foo"
  • 首先将 ref 转换为值:value == *b"foo"

来自 C++(其中值和引用几乎是同一件事),这两种方法对我来说看起来都有点奇怪。比较值和引用的最惯用的方法是什么?

Ale*_*uze 3

在 rust 中T&T(以及&mut T)是不同的类型。虽然不同类型可以进行比较,但并不是标准的。相等比较(==运算符)是通过PartialEq特征完成的。它看起来像这样:

pub trait PartialEq<Rhs = Self> where
    Rhs: ?Sized,
{
    fn eq(&self, other: &Rhs) -> bool;

    fn ne(&self, other: &Rhs) -> bool { ... }
}
Run Code Online (Sandbox Code Playgroud)

尽管它是通用的Rhs(意味着一种类型可以与许多其他类型进行比较),但它默认为Self.

因此,回到您的示例,您可以只编写value.eq(b"foo")(这将比较引用的值),但尽管它没有错,但可能更常见的是&value == b"foo". 取消引用也很好,但我很少看到它。

您也不必担心类型及其引用之间的相等性会有所不同,因为标准库具有以下总体实现(以及其他可变引用):

impl<A, B> PartialEq<&B> for &A where
    A: PartialEq<B> + ?Sized,
    B: ?Sized, 
{ ... }
Run Code Online (Sandbox Code Playgroud)

这会以正确的方式自动实现引用的相等性。