`Some()` 的语法是什么?

What is the syntax of `Some()`?

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
    

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

当您定义具有各种变体类型的枚举时:

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 为方便起见全局使用它。

It looks like a function, but didn't find relevant source code for it.

正确地说,每次使用都是一个 enum 构造函数 除了它的定义之外,它没有任何来源,但实际上你 可以 使用 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) -> T 时出现错误,因为 const 功能仍在开发中,尚未稳定所有未来的使用。这适用于 Option::unwrap,因为作为标准库的一部分,它得到了特殊对待。

您可以在此处阅读有关 Option 的其他 const 函数的更多信息:https://github.com/rust-lang/rust/issues/67441. Or see information on the development of const fns in general here: https://github.com/rust-lang/rust/issues/57563