是否应该在枚举之前取消引用枚举?

KCh*_*oux 3 pattern-matching dereference rust

作为Rust的新手,我偶然发现了两种明显有效的运行match参考类型的方法.

我已经定义了一个枚举:

enum Color {
    Red,
    Yellow,
    Green,
    Teal,
    Blue,
    Purple,
}
Run Code Online (Sandbox Code Playgroud)

我想实现一个函数,该函数适用&self于此枚举实例的引用.

我可以看到两种方法来编写这样的函数:

impl Color {
    // Approach #1: Match the reference, using references in each pattern
    fn contains_red(&self) -> bool {
        match self {
            &Color::Red => true,
            &Color::Yellow => true,
            &Color::Purple => true,
            _ => false,
        }
    }

    // Approach #2: Dereference &self and match the patterns directly
    fn contains_blue(&self) -> bool {
        match *self {
            Color::Blue => true,
            Color::Teal => true,
            Color::Purple => true,
            _ => false,
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我预计解除引用&self将被视为一个移动,并且如果我color.contains_blue()连续两次调用同一个实例会导致错误,但似乎并非如此.

这些方法在功能上是否相同?如果我匹配更复杂的物体,他们中的一个会崩溃吗?

Vee*_*rac 6

您不能移出不可变引用,因此您不必担心这种情况.

值得考虑的是,人们会期望匹配工作有点类似于(Partial)Eq,这需要&self.换句话说,除非被迫,否则人们会期望隐含地引用它.通过一些实验很容易证实这一点.

值得一提的是,*self不是一招-这是一个内存位置的参考.因此它是一个左值.人机工程学,

当head表达式是左值时,匹配不会分配临时位置(但是,按值绑定可以从左值复制或移动).

https://doc.rust-lang.org/reference.html#match-expressions

如果未分配临时位置,则无法进行移动.因此行为得到保证.作为括号内容,内部数据仍然可以从解构模式中移出,这会导致问题.但是,无论您是匹配self还是匹配,都是如此*self.

使用*self似乎是一种非正式的习语,应该是首选.