为什么解构借用的 Enum 需要取消引用其字段?

问题描述

考虑以下片段:

use std::fmt;

enum TestEnum {
    StructMem {value: i32,is_valid: bool},RandoMem,}

impl fmt::display for TestEnum {
    fn fmt(&self,f: &mut fmt::Formatter<'_>) -> fmt::Result {
        use TestEnum::*;
        match self {
            StructMem {value,is_valid} => {
                if *is_valid { // Why dereference is_valid ?
                    write!(f,"f")?
                }
                write!(f,"{:?}",value)
            }
            RandoMem => {
                f.write_str("Random")
            }
        }
    }
}

为什么我需要在 is_valid 语句中取消引用 if

编辑:这个问题 What is the syntax to match on a reference to an enum? 似乎在处理类似的情况,但答案都集中在解决特定问题(不涉及结构)上,而不是解释所有权/绑定语义。

解决方法

这不是特定于 matchenum 而是由于 fmt() 的签名,它将 self 作为参考(&self 代替self,如果所有权已被取得)。

因此,match self 已经引用了 TestEnum 的借用实例,并且匹配臂 StructMem {value,is_valid} 通过引用(&i32&bool )。这就是为什么 is_valid 最终成为 &bool 而不是 bool

,

当您对引用进行模式匹配并对其进行解构时,您只能获得内部成员的引用,否则您会将内部成员从不可变的引用中移出,这将违反 Rust 的所有权规则。这是一个更简单的例子:

struct Container(Vec<i32>);

fn get_inner_vec(c: &Container) -> &Vec<i32> {
    // v MUST BE a reference
    // otherwise this destructing would somehow be moving the Vec
    // outside of an immutable borrow of Container
    let Container(v) = c;
    v
}