1

我们如何能够将 type 作为参数而不是 turbofish 传递给syn::parse::ParseBuffer::peek

方法通常称为 like input.parse::<Token![;]>()。我们将类型作为泛型传递,但 peek 期望它们为input.peek(Token![;]).

我想知道,因为如果我创建一个类型别名Token![;] liketype TokenAlias = Token![;]并使用它 like input.peek(TokenAlias),我会收到错误:

expected value, found type alias `TokenAlias` can't use a type alias as a constructor

Token![;]如果也不允许,这将是有道理的。

为什么我在使用类型别名时会收到此错误?

代码TokenAlias

// COMPILE ERROR: expected value, found type alias `TokenAlias` can't use a type alias as a constructor

type TokenAlias = Token![;];

impl Parse for PathSegments {
    fn parse(input: ParseStream) -> Result<Self> {
        let mut segments = Punctuated::new();

        let first = parse_until(input, TokenAlias)?;
        segments.push_value(syn::parse2(first)?);

        while input.peek(TokenAlias) {
            segments.push_punct(input.parse()?);

            let next = parse_until(input, TokenAlias)?;
            segments.push_value(syn::parse2(next)?);
        }

        Ok(PathSegments { segments })
    }
}

操场

代码Token![;]

// BUILDS SUCCESSFULLY

impl Parse for PathSegments {
    fn parse(input: ParseStream) -> Result<Self> {
        let mut segments = Punctuated::new();

        let first = parse_until(input, Token![;])?;
        segments.push_value(syn::parse2(first)?);

        while input.peek(Token![;]) {
            segments.push_punct(input.parse()?);

            let next = parse_until(input, Token![;])?;
            segments.push_value(syn::parse2(next)?);
        }

        Ok(PathSegments { segments })
    }
}

操场

以下是peekfrom的源代码syn

pub fn peek<T: Peek>(&self, token: T) -> bool {
    let _ = token;
    T::Token::peek(self.cursor())
}

源代码

4

1 回答 1

1

peek函数接受令牌,而不是类型。

它接受的原因Token[;]是它扩展为一个标识符,它是一个类型的名称,也是一个隐藏在文档中的全局函数!您的类型别名是指类型,并且尝试使用构造函数语法为类似单元的结构构造值会使编译器抱怨这种语法不适用于类型别名。(即使是这样,Semi它也不是一个类似单元的结构,所以它特别不适用于那种类型。)

于 2021-05-16T10:26:20.533 回答