为什么Rust有结构和枚举?

bpzcxfmw  于 2023-01-02  发布在  其他
关注(0)|答案(6)|浏览(170)

Rust的枚举是代数数据类型。据我所知,这似乎包含了struct是什么。struct有什么不同之处,需要保留它?

a64a0gku

a64a0gku1#

首先,您是正确的,就其所能表示的内容而言,enum在语义上严格上级struct,因此struct有些多余。
然而,还有其他因素在起作用。

  • 易用性:enum内的值只能通过匹配(直接)访问;与访问struct字段的易用性相比,您可以为每个字段编写访问器,但这确实很麻烦。
  • 区别:enum是标记并集,struct具有固定布局;我们(程序员)通常喜欢给事物加上标签,因此可以理解为不同的功能赋予不同的名称。

在我看来,struct因此是句法上的糖,我通常更喜欢简洁和平均,但是一点糖可以大大增加简洁的表达。

blmhpbnm

blmhpbnm2#

首先,Rust具有广泛的数据类型:

  • 具有命名字段的结构(struct Foo {bar: uint}
  • 元组结构(struct Foo(pub Bar, Baz)
  • 没有字段的结构(struct Foo;
  • 枚举,具有各种类型的变量:
  • 无字段的变体(例如None
  • 元组变体(例如Some(T)
  • 结构变体(例如Some { pub inner :T }

这给了程序员定义数据类型的灵活性。通常,你不需要命名字段,特别是当struct/variant只有一个字段时。在这种情况下,Rust允许你使用tuple struct/tuple variant。
如果从Rust中删除了结构体,那么功能上不会有任何损失,带有结构体变体的枚举可以再次使用。但是会有大量的单变体枚举,这将是不必要的,而且使用起来很麻烦。

cpjpxq1n

cpjpxq1n3#

不是100%正确,但另一个很好的方式来考虑它:enum实际上并不上级struct,语法上的糖衣只是让它看起来像是。
enum是一个sum类型,意味着它的值是一组其他类型中的一个值。Result<T, E>类型是TE类型的 * 任一个 。因此,每个enum变量都有一个类型与之关联。其他任何东西(没有类型、元组变量和结构变量) 都可能 * 是语法糖。

enum Animal {
    // without syntax sugar
    Cat(i32),  
    // desugars to `Dog(())` (empty tuple/unit) 
    Dog,
    // desugars to `Horse((i32, bool))` (tuple)
    Horse(i32, bool),
    // desugars to `Eagle(GeneratedEagleType)` and a struct definition outside
    // of this enum `struct GeneratedEagleType { weight: i32, male: bool }`
    Eagle { weight: i32, male: bool }
}

因此,如果每个enum变体只与一个类型相关联就足够了,在这种情况下,enum并不上级struct,因为它不能构造产品类型(如struct)。
能够将“类型定义”写在枚举变量定义中只是为了方便。
还有:struct也上级“元组结构”和“元组”。如果我们忽略名称,那三样东西是nearly等价的。但是为了方便起见,Rust仍然有这三种不同的类型。
请注意,我不知道这些枚举定义是否真的是语法糖,但它们 * 可能 * 是,这可能有助于思考

nsc4cvqm

nsc4cvqm4#

可见性

不是要在可能是暂时的实现细节中寻找原因(我不是核心团队的成员,没有洞察力),而是

  • 公共枚举不能持有或包含私有结构。
  • 公共结构可以保存或包含私有枚举。

另见

k10s72fa

k10s72fa5#

你是对的,枚举和特征以及它们通过结构体的继承都实现了代数数据类型。
然而traits是一个可扩展的类型集合,任何结构都可以被赋予来自任何代码的trait。使用内省,可以期望一个具有给定trait的值,并动态地挖掘出一个结构的实际类型。但是该类型是不可预测的类型集合之一,因为任何结构都可以从任何地方被赋予所述trait。
然而,枚举定义了一个有限的类型层次结构,使得匹配子类型就像它们是简单的值一样是可预测的和直接的。因此,围绕枚举的语言特性可以被优化,以便类型检查静态地发生,提供更好的性能,并在语言中提供一些糖。而且层次结构描述包含在枚举定义中。并且不影响特征类型系统。
TL;DR:enum以一种包含的方式缩小了类型的层次结构,而不是依赖于可由任何代码段扩展并影响一切的特性。

vs3odd8k

vs3odd8k6#

除了上述答案之外,另一个重要的区别是枚举在某个点上只能是所声明的值之一,而结构表示该示例的所有参数的值。

enum Things{
Box, 
Page(i32),
}

struct Things{
box: Option<String>,
page: i32,
}

在上面的例子中,单个枚举可以是Box或Page,而struct的单个示例将表示Box和Page。

相关问题