将枚举变体用作函数的奇怪语法是什么?

问题描述 投票:2回答:1

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

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 libs的一种特殊语法?如果是后者,是否有proc_macro特定语法规则的文档?

rust rust-proc-macros
1个回答
4
投票

此语法是标准的Rust语法。您可以使用tuple struct或tuple struct-like enum variants作为函数。看到这个小例子:

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中找到有关此功能的更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.