【问题标题】:What is this strange syntax where an enum variant is used as a function?将枚举变体用作函数的这种奇怪语法是什么?
【发布时间】:2019-02-21 08:02:57
【问题描述】:

下面是syn::parse的mod文档给出的example

enum Item {
    Struct(ItemStruct),
    Enum(ItemEnum),
}

struct ItemStruct {
    struct_token: Token![struct],
    ident: Ident,
    brace_token: token::Brace,
    fields: Punctuated<Field, Token![,]>,
}

impl Parse for Item {
    fn parse(input: ParseStream) -> Result<Self> {
        let lookahead = input.lookahead1();
        if lookahead.peek(Token![struct]) {
            input.parse().map(Item::Struct)    // <-- here
        } else if lookahead.peek(Token![enum]) {
            input.parse().map(Item::Enum)      // <-- and here
        } else {
            Err(lookahead.error())
        }
    }
}

input.parse().map(Item::Struct) 是有效的正常 Rust 语法(似乎不是 Item::Struct 不是函数),还是 proc_macro 库的一种特殊语法?如果是后者,是否有proc_macro具体语法规则的文档?

【问题讨论】:

    标签: rust rust-proc-macros


    【解决方案1】:

    这个语法是标准的 Rust 语法。 您可以使用元组结构或类似元组结构的枚举变体作为函数。请看这个小例子:

    enum Color {
        Str(String),
        Rgb(u8, u8, u8),
    }
    
    struct Foo(bool);
    
    // Use as function pointers (type annotations not necessary)
    let f: fn(String) -> Color = Color::Str;
    let g: fn(u8, u8, u8) -> Color = Color::Rgb;
    let h: fn(bool) -> Foo = Foo;
    

    在下一个示例中,这些函数直接传递给另一个函数(如Option::map)(Playground):

    // A function which takes a function
    fn string_fn<O, F>(f: F) -> O
    where
        F: FnOnce(String) -> O,
    {
        f("peter".to_string())
    }
    
    
    string_fn(|s| println!("{}", s));  // using a clojure 
    string_fn(std::mem::drop);         // using a function pointer
    
    // Using the enum variant as function
    let _: Color = string_fn(Color::Str); 
    

    您可以在this chapter of the book 中找到有关此功能的更多信息。

    【讨论】:

    • 感谢示例和本书参考!
    猜你喜欢
    • 1970-01-01
    • 2021-01-12
    • 2012-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-21
    • 2022-11-20
    相关资源
    最近更新 更多