What is this strange syntax where an enum variant is used as a function?

我的梦境 提交于 2020-01-21 12:53:01

问题


Below is the example given by the mod documentation of 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())
        }
    }
}

Is input.parse().map(Item::Struct) a valid normal Rust syntax (appears not as Item::Struct is not a function), or is it a kind of special syntax for proc_macro libs? If the latter is the case, is there a documentation of the proc_macro specific syntax rules?


回答1:


This syntax is standard Rust syntax. You can use tuple struct or tuple struct-like enum variants as functions. See this small example:

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;

In the next example, those functions are directly passed to another function (like 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); 

You can find out more about this feature, in this chapter of the book.



来源:https://stackoverflow.com/questions/54802045/what-is-this-strange-syntax-where-an-enum-variant-is-used-as-a-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!