簡體   English   中英

為什么Rust有struct和enum?

[英]Why does Rust have struct and enum?

Rust 的枚舉是代數數據類型。 據我所知,這似乎包含了 struct 是什么。 需要保留它的結構有什么不同?

首先,您是正確的,語義enum在它可以表示的內容方面嚴格優於struct ,因此struct有點多余。

然而,這里還有其他因素在起作用。

  • 易用性: enum的值只能通過匹配(直接)訪問; 與訪問struct字段的易用性形成對比。 您可以為每個字段編寫訪問器,但這真的很麻煩。

  • 區別: enum是標記聯合, struct具有固定布局; 我們(程序員)通常喜歡給事物貼上標簽,因此可以為不同的功能賦予不同的名稱。

在我看來, struct因此是語法糖。 我通常更喜歡精益和吝嗇,但一點糖可以大大增加可以簡潔表達的內容。

首先,Rust 有多種數據類型:

  • 具有命名字段的struct Foo {bar: uint}struct Foo {bar: uint}
  • 元組結構( struct Foo(pub Bar, Baz)
  • 沒有字段的struct Foo;struct Foo;
  • 枚舉,具有各種類型的變體:
    • 沒有字段的變體(例如None
    • 元組變體(例如Some(T)
    • 結構變體(例如Some { pub inner :T }

這為程序員定義數據類型提供了一定的靈活性。 通常,您不想要命名字段,尤其是在結構/變體只有一個字段的情況下。 在這種情況下,Rust 允許您使用元組結構/元組變體。

如果從 Rust 中刪除結構體,則不會失去功能,可以再次使用具有結構體變體的枚舉。 但是將會有大量的單變量枚舉,這將是不必要的並且使用起來很麻煩。

不是 100% 正確,而是另一種很好的思考方式: enum實際上並不優於struct ,語法糖只是讓它看起來像。

enum是一種和類型,這意味着它的值是一組其他類型中的一個值。 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也優於“元組結構”和“元組”。 如果我們忽略名稱,那么這三件事幾乎是等價的。 但是為了方便起見,Rust 仍然有這三種不同的類型。


請注意,我不知道這些枚舉定義是否實際上是語法糖。 但他們可能是,這可能有助於思考。

能見度

不要在可能是短暫的實現細節中找到原因(我不在核心團隊中並且沒有洞察力),但是

  • 公共枚舉不能持有或包含私有結構。
  • 公共結構可以保存或包含私有枚舉。

也可以看看

您是對的,枚舉和特征以及它們通過結構的繼承都實現了代數數據類型。

然而,traits 是一組可擴展的類型,其中任何 stuct 都可以歸因於任何代碼段的任何 trait。 使用自省,可以期望具有給定特征的值,並動態挖掘結構的實際類型。 但該類型屬於一組不可預測的類型,因為任何結構都可以從任何地方獲得所述特征。

而枚舉一勞永逸地定義了一個有限的類型層次結構,使得匹配子類型變得可預測和直接,就像它們是簡單的值一樣。 因此可以優化圍繞枚舉的語言特性,以便靜態進行類型檢查,提供更高的性能,並在語言中添加一些糖。 而且層次描述包含在枚舉定義中,並且不會影響特征類型系統。

TL;DR:enum 以一種包含的方式縮小了類型的層次結構,而不是依賴於可被任何代碼段擴展並影響一切的特征。

與上述答案一起的另一個重要區別是,枚舉在一個點上只能是聲明的值之一,而結構表示該實例的所有參數的值。 例如。

enum Things{
Box, 
Page(i32),
}

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

在上述情況下,單個枚舉可以是一個框或一個頁面,而單個結構實例將代表一個框一個頁面。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM