1

我正在查看nomrust 的 crate,其中包含许多解析字节/字符的函数。

许多函数,例如tag()下面看到的,处理输入不是作为函数的参数提供的,而是出现在第二组括号中,跟在我称之为参数的后面。在示例中,如果在haystack中寻找针头,则该函数使用它自己的参数,这是指定needle的方式,但haystack是单独指定的,在参数括号之后,在它自己的括号内 (也许是因为它是一个单值元组?)。tag()

use nom::bytes::complete::tag;

fn parser(s: &str) -> IResult<&str, &str> {
  tag("Hello")(s)
}

在上面的示例中,tag()的工作是测试输入是否以s开头Hello。您可以调用parser,并传入“Hello 大家!”,该tag()函数确实验证了开头sHello。但是如何(s)找到它的方式tag()

有人可以向我解释这种语法,或者显示在哪里阅读它。它有效,我可以使用它,但我不明白我在看什么!

谢谢

4

2 回答 2

2

tag()is的返回值impl Fn(Input) -> IResult<Input, Input, Error>,即函数返回另一个函数。第一组括号用于调用tag();第二组用于调用它返回的函数。

这允许您将这些函数返回的“解析器”存储在一个变量中并多次使用它。或者,换一种说法,您也可以编写而不是问题中的函数定义

let parser = tag("Hello");

然后parser以与调用函数相同的方式调用。

于 2021-01-25T12:55:08.693 回答
0

tag("Hello")只返回一个函数,然后立即使用参数调用该函数s,即tag("Hello")(s). 这是一个简单的实现示例:

fn tag<'a>(needle: &'a str) -> impl Fn(&str) -> bool + 'a {
    move |haystack: &str| haystack.starts_with(needle)
}

fn parser(s: &str) -> bool {
    tag("Hello")(s)
}

fn main() {
    println!("{}", parser("Hello everbody!")); // true
    println!("{}", parser("Bye everybody!")); // false
}

操场

于 2021-01-25T13:02:10.840 回答