【问题标题】:What is the syntax of `Some()`?`Some()` 的语法是什么?
【发布时间】:2021-07-19 21:45:27
【问题描述】:

Rust 中,Option 枚举声明为:

pub enum Option<T> {
    /// No value
    #[lang = "None"]
    #[stable(feature = "rust1", since = "1.0.0")]
    None,
    /// Some value `T`
    #[lang = "Some"]
    #[stable(feature = "rust1", since = "1.0.0")]
    Some(#[stable(feature = "rust1", since = "1.0.0")] T),
}

我们知道Option 值可以通过以下方式创建:

Some("Apple")

问题

  1. Some(T)Some("Apple") 的语法是什么?
    貌似是个函数,但是没找到相关的源码。

  2. 当我尝试创建一个类似的枚举时,如:

    pub enum Food<T> {
        Fruit(T),
    }
    
    impl<T> Food<T> {
        pub const fn unwrap(self) -> T {
            match self {
                Self::Fruit(val) => val,
            }
        }
    }
    
    fn x() {
        let a = Food::Fruit("apple");
        println!("{}", a.unwrap());
    }
    

    并得到错误:

     error[E0493]: destructors cannot be evaluated at compile-time
       --> src/lib.rs:6:25
        |
     6  |     pub const fn unwrap(self) -> T {
        |                         ^^^^ constant functions cannot evaluate destructors
     ...
     10 |     }
        |     - value is dropped here
    

    是否可以创建这样的枚举?如果是这样,如何解决这些问题?

【问题讨论】:

  • 去掉const就可以了?
  • 您应该将您的问题分成两个单独的帖子。它们之间并没有真正的关系。
  • @kmdreko 第二个问题只是想弄清楚第一个问题问的是什么,如果可以回答第一个问题,那么可以忽略第二个问题。
  • @Herohtar 是的,删除 unwrap() 上的 const 确实有效。
  • 你使用的是EnumTuple,它暗示了一个元组构造函数doc.rust-lang.org/stable/reference/expressions/…

标签: rust enums syntax


【解决方案1】:

当您使用各种变体类型定义枚举时:

pub enum Food {
    Onion,
    Fruit(String),
    Pizza { toppings: Vec<Food> },
}

通过变体类型创建该枚举实例的语法如下:

let o: Food = Food::Onion;
let f: Food = Food::Fruit("Mango".to_string());
let p: Food = Food::Pizza { toppings: vec![] };

如果这样导出元组变体,它们可以独立存在(没有Food::):

use Food::*; // brings Onion, Fruit, and Pizza into scope

let o: Food = Onion;
let f: Food = Fruit("Mango".to_string());
let p: Food = Pizza { toppings: vec![] };

为方便起见,Option::NoneOption::Some 在全局范围内使用它。

看起来像一个函数,但没有找到相关的源代码。

正确地,每个使用都是一个 枚举构造函数,它除了定义之外没有其他来源,但实际上您 可以Fruit 用作函数:

fn convert<T, U, F: Fn(T) -> U>(f: F, t: T) -> U {
    f(t)
}

fn main() {
    let f: Food = convert(Food::Fruit, "mango".to_string());
}

定义pub const fn unwrap(self) -&gt; T 时会出现错误,因为const 函数仍在开发中,并且未来的所有使用都尚未稳定。这适用于Option::unwrap,因为作为标准库的一部分,它得到了特殊处理。

您可以在此处阅读有关 Option 的其他 const 函数的更多信息:https://github.com/rust-lang/rust/issues/67441。或者在这里查看const fns 的一般发展信息:https://github.com/rust-lang/rust/issues/57563

【讨论】:

  • 所以,关于第一个问题:简单地说,在字段中,() 是元组,{} 是结构;因此Some(T) 只是一个带有T 类型的单个项目的元组。
  • Some 是“元组变体”,None 是“单元变体”,Pizza {} 是“结构变体”。相似之处肯定存在,但要小心; Some(T)不是元组,元组的类型为(T),而Some(T) 的类型为Option&lt;T&gt;。希望能解决问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多