Rust 1-66 新特性:枚舉值的顯示判定

Rust 1.66 版本增加了帶有字段的枚舉類型,用戶可以進行值的指定。這是什麼意思?讓我們看一個例子:

1#[repr(u8)]
2enum Bar {
3    A,
4    B,
5    C = 42,
6    D,
7}

在這裏,變量 A、B、C 和 D 的值分別爲 0、1、42 和 43。在 Rust 1.65 之前的版本,這樣是沒有問題的。但是如果任何一個變量指定了字段,上面的代碼將無法編譯 - 如下所示:

1#[repr(u8)]
2enum Foo {
3    A(bool, String) = 100,
4    B,
5    C,
6}

在上面的枚舉類型 Foo 中,變體類型 A 有兩個類型爲 bool 和 String 的字段,這將導致編譯失敗。

在 rust 1.66 的最新穩定版本中,非單位類型 (即帶字段的變體) 的顯式指定已被放寬。完整代碼如下:

1use std::mem::discriminant;
 2
 3#[repr(u8)]
 4enum Bar {
 5    A,
 6    B,
 7    C = 42,
 8    D,
 9}
10
11#[repr(u8)]
12enum Foo {
13    A(bool, String) = 100,
14    B,
15    C,
16}
17
18fn main() {
19    println!("Bar::A discriminant-> {:?}", discriminant(&Bar::A));
20    println!("Bar::B discriminant-> {:?}", discriminant(&Bar::B));
21    println!("Bar::C discriminant-> {:?}", discriminant(&Bar::C));
22    println!("Bar::D discriminant-> {:?}", discriminant(&Bar::D));
23
24    println!("Bar::A discriminant-> {}", Bar::A as u8);
25    println!("Bar::B discriminant-> {}", Bar::B as u8);
26    println!("Bar::C discriminant-> {}", Bar::C as u8);
27    println!("Bar::D discriminant-> {}", Bar::D as u8);
28
29    println!("Foo::A discriminant-> {:?}", discriminant(&Foo::A(true, String::new())));
30    println!("Foo::B discriminant-> {:?}", discriminant(&Foo::B));
31    println!("Foo::C discriminant-> {:?}", discriminant(&Foo::C));
32}

執行結果:

Bar::A discriminant-> Discriminant(0)
Bar::B discriminant-> Discriminant(1)
Bar::C discriminant-> Discriminant(42)
Bar::D discriminant-> Discriminant(43)
Bar::A discriminant-> 0
Bar::B discriminant-> 1
Bar::C discriminant-> 42
Bar::D discriminant-> 43
Foo::A discriminant-> Discriminant(100)
Foo::B discriminant-> Discriminant(101)
Foo::C discriminant-> Discriminant(102)

它有什麼幫助?一般來說,開發者不需要直接處理判定值。但是當跨語言邊界傳遞類型時,它很方便,因爲枚舉類型必須在兩個方向上匹配。

本文翻譯自:

https://rbsomeg.medium.com/explicit-discriminant-value-for-enum-variants-52cb508ace92

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/ZHjcajO9sXxkPWsLozA8nQ