【问题标题】:Why can't I access enum fields directly?为什么我不能直接访问枚举字段?
【发布时间】:2021-03-12 14:50:03
【问题描述】:

我只是在学习 Rust。 所以我知道这是可行的:

enum Animal {
    Cat { name: String, weight: f64 }
}

fn main() {
    let a = Animal::Cat { name: "Spotty".to_string(), weight: 2.7 };
    match a {
        Animal::Cat{name, weight} => { println!("Cat n={} w={}", name, weight); }
    }
}

但是为什么我不能像这样直接从枚举字段分配:

    ...
    let wt = a.weight;

还是我使用了错误的语法?还是因为 Rust 不能保证 Animal 实例的类型是 Cat? 是使用match 访问枚举结构或元组变体实例的字段的唯一方法吗?

【问题讨论】:

标签: rust enums


【解决方案1】:

这是因为weight 不是Animal 枚举的一部分,它是Cat 枚举类型的一部分。假设将来您添加了另一种没有体重信息的动物:

enum Animal {
    Cat { name: String, weight: f64 },
    Insect { species: String, height: f64 },
}

那么a.weight 并不总是有值。您可以使用if letmatch 有条件地从enum 获取数据(如果存在):

if let Animal::Cat { weight, .. } = a {
    println!("Your cat weights {} kg.", weight);
} else {
    println!("get a cat");
};

【讨论】:

  • 更正:Cat 不是一个类型,它是一个项目(/变体/构造函数)。将变体变成类型 is a recurring one 的想法,但截至 2021 年 3 月,情况并非如此。
【解决方案2】:

还是因为 Rust 不能保证 Animal 实例的类型是 Cat?

是的。在一个普通的枚举中,你会有多个变体,它们可能有也可能没有相同的类型,因此也有字段(实际上有些可能根本没有字段)。

因此,虽然 rust 在技术上可以通过单个变体或所有变体都具有属性的兼容版本的情况下对枚举进行属性访问,但这些情况很少见,它们并不重要,而且这种情况的价值复杂性基本上为零。

我没有正确地看到使用单变量枚举的意义,你为什么不只是使用结构?

struct Cat { name: String, weight: f64 }

?

是使用 match 访问枚举结构或元组变体实例的字段的唯一方法吗?

您也可以使用if let,尽管这基本相同。 或者您可以有一个公开信息的方法(内部带有matchif let),为了方便(或者因为变体是私有的)。

【讨论】:

  • 在我的实际代码中,我有几个变体。只是想发布一个精简版。
  • @user1088084 如果所有Animals 都有weight,请考虑将struct Animal { weight: f64, species: Species }enum Species { Cat { name: String }, Squirrel { color: Color } } 或类似的东西结合起来,而不是试图将其全部塞入一个扁平的枚举中。结构和枚举被称为代数数据类型,因为它们在某些方面遵循类似于数字的规则:(weight*name)+(weight*color) 可以简化为weight + (name*color)
  • 嗯,我完全倒退了,显然应该是weight*(name+color)。这条消息是由于睡眠不足而带给你的
猜你喜欢
  • 1970-01-01
  • 2010-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多