简体   繁体   English

为什么Rust有struct和enum?

[英]Why does Rust have struct and enum?

Rust's enums are algebraic datatypes. Rust 的枚举是代数数据类型。 As far as I can tell this seems to subsume what struct is.据我所知,这似乎包含了 struct 是什么。 What is different about struct that necessitates keeping it?需要保留它的结构有什么不同?

First of all, you are correct that semantically enum is strictly superior to the struct as to what it can represent, and therefore struct is somewhat redundant.首先,您是正确的,语义enum在它可以表示的内容方面严格优于struct ,因此struct有点多余。

However, there are other elements at play here.然而,这里还有其他因素在起作用。

  • ease of use: the values within an enum can only be accessed (directly) through matching;易用性: enum的值只能通过匹配(直接)访问; contrast with the ease of use of accessing a struct field.与访问struct字段的易用性形成对比。 You could write accessors for each and every field, but that is really cumbersome.您可以为每个字段编写访问器,但这真的很麻烦。

  • distinction: an enum is a tagged union, a struct has a fixed-layout;区别: enum是标记联合, struct具有固定布局; we (programmers) generally like to put labels on things, and therefore giving different names to different functionality can be appreciated.我们(程序员)通常喜欢给事物贴上标签,因此可以为不同的功能赋予不同的名称。

As I see it, struct is therefore syntactic sugar.在我看来, struct因此是语法糖。 I usually prefer lean and mean, but a bit of sugar can go a long way in increasing what can be represented tersely.我通常更喜欢精益和吝啬,但一点糖可以大大增加可以简洁表达的内容。

Firstly, Rust has a wide array of data types:首先,Rust 有多种数据类型:

  • Structs with named fields ( struct Foo {bar: uint} )具有命名字段的struct Foo {bar: uint}struct Foo {bar: uint}
  • Tuple structs ( struct Foo(pub Bar, Baz) )元组结构( struct Foo(pub Bar, Baz)
  • Structs with no fields ( struct Foo; )没有字段的struct Foo;struct Foo;
  • Enums, with various types of variants:枚举,具有各种类型的变体:
    • Variants with no fields (eg None )没有字段的变体(例如None
    • Tuple variants (eg Some(T) )元组变体(例如Some(T)
    • Struct variants (eg Some { pub inner :T } )结构变体(例如Some { pub inner :T }

This gives the programmer some flexibility in defining datatypes.这为程序员定义数据类型提供了一定的灵活性。 Often, you don't want named fields, especially if the struct/variant has only one field.通常,您不想要命名字段,尤其是在结构/变体只有一个字段的情况下。 Rust lets you use tuple structs/tuple variants in that case.在这种情况下,Rust 允许您使用元组结构/元组变体。

If structs were removed from Rust there would be no loss of functionality, enums with struct variants could be used again.如果从 Rust 中删除结构体,则不会失去功能,可以再次使用具有结构体变体的枚举。 But there would be an overwhelming number of single-variant enums which would be unnecessary and cumbersome to use.但是将会有大量的单变量枚举,这将是不必要的并且使用起来很麻烦。

Not 100% correct, but another nice way to think about it : enum isn't actually superior to struct , the syntax sugar just makes it look like it is.不是 100% 正确,而是另一种很好的思考方式: enum实际上并不优于struct ,语法糖只是让它看起来像。

An enum is a sum type meaning that it's value is one value of one of a set of other types. enum是一种和类型,这意味着它的值是一组其他类型中的一个值。 The Result<T, E> type is either of type T or E .Result<T, E>类型是类型的TE So each enum variant has exactly one type associated with it.因此,每个enum变体都只有一种类型与之关联。 Everything else (no type, tuple variants and struct variants) could be syntax sugar.其他一切(无类型、元组变体和结构变体)都可以是语法糖。

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 }
}

So it would be enough if each enum variant would be associated with exactly one type.因此,如果每个enum变体都与一种类型相关联就足够了。 And in that case enum is not superior to struct , because it cannot construct product types (like struct ).在那种情况下enum并不优于struct ,因为它不能构造产品类型(如struct )。

To be able write the "type definition" inside the enum variant definition is just for convenience.能够在枚举变体定义中编写“类型定义”只是为了方便。

Also: struct is superior to "tuple structs" and "tuples", too.另外: struct也优于“元组结构”和“元组”。 If we ignore the names those three things are nearly equivalent.如果我们忽略名称,那么这三件事几乎是等价的。 But Rust still has those three different kinds of types for convenience.但是为了方便起见,Rust 仍然有这三种不同的类型。


Please note that I don't know if those enum definitions are actually syntax sugar or not.请注意,我不知道这些枚举定义是否实际上是语法糖。 But they could be and that might help think about.但他们可能是,这可能有助于思考。 it

Visibility能见度

Not to find reason in what may be a transient implementation detail (I'm not on the core team and have no insight), but不要在可能是短暂的实现细节中找到原因(我不在核心团队中并且没有洞察力),但是

  • A public enum can not hold or contain a private struct.公共枚举不能持有或包含私有结构。
  • A public struct can hold or contain a private enum.公共结构可以保存或包含私有枚举。

See also也可以看看

You are right that enums and traits and their inheritance by structs both implement algebraic datatypes.您是对的,枚举和特征以及它们通过结构的继承都实现了代数数据类型。

However traits is an extensible set of types, where any stuct can be attributed any trait from any piece of code.然而,traits 是一组可扩展的类型,其中任何 stuct 都可以归因于任何代码段的任何 trait。 Using introspection, it is possible to expect a value with a given trait, and dynamically dig out the actual type of a struct.使用自省,可以期望具有给定特征的值,并动态挖掘结构的实际类型。 But that type is among a set of types that is unpredictable, because any struct could be given the said trait from anywhere.但该类型属于一组不可预测的类型,因为任何结构都可以从任何地方获得所述特征。

Whereas enums define once and for all a limited type hierarchy, making it predictable and straightforward to go match subtypes as if they were simple values.而枚举一劳永逸地定义了一个有限的类型层次结构,使得匹配子类型变得可预测和直接,就像它们是简单的值一样。 The language features surrounding enums can therefore be optimized so that the type checks occur statically, providing much greater performance, and some sugar in the language.因此可以优化围绕枚举的语言特性,以便静态进行类型检查,提供更高的性能,并在语言中添加一些糖。 But also the hierarchy description is contained to the enum definition, and does not impact the trait type system.而且层次描述包含在枚举定义中,并且不会影响特征类型系统。

TL;DR: enum narrows down a hierarchy of types in a contained manner, instead of relying on traits that are extensible by any piece of code and impacts everything. TL;DR:enum 以一种包含的方式缩小了类型的层次结构,而不是依赖于可被任何代码段扩展并影响一切的特征。

Another important distinction along with the above answers is that enum at one point can ONLY be one of the values stated while struct represents values for all the parameters for that instance.与上述答案一起的另一个重要区别是,枚举在一个点上只能是声明的值之一,而结构表示该实例的所有参数的值。 eg.例如。

enum Things{
Box, 
Page(i32),
}

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

In the above case a single enum can either be a Box or a Page, while a single instance of struct will represent a box and a page.在上述情况下,单个枚举可以是一个框或一个页面,而单个结构实例将代表一个框一个页面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM