我正在看nom
crate for rust,它包含许多解析字节/字符的函数。
许多函数,如下面所见的tag()
,处理的输入不是作为函数的参数提供的,而是出现在第二组括号中,后面是我称之为参数的东西。例如,如果在haystack中查找指针,则tag()
函数使用自己的参数,这就是指定指针的方式,但是haystack是单独指定的,在参数括号之后,在自己的括号内(可能因为它是单值元组?)。
use nom::bytes::complete::tag;
fn parser(s: &str) -> IResult<&str, &str> {
tag("Hello")(s)
}
在上面的例子中,tag()
的任务是测试输入的s
是否以Hello
开头。你可以调用parser
,传入"Hello everybody!,tag()
函数确实验证了s
的开头是Hello。但是(s)
是如何进入tag()
的呢?
谁能给我解释一下这个语法,或者告诉我在哪里可以读到它。它可以工作,我可以使用它,但我不明白我在看什么!
感谢tag()
的返回值为impl Fn(Input) -> IResult<Input, Input, Error>
,即该函数返回另一个函数。第一组圆括号用于调用tag()
;第二组用于调用它返回的函数。
这允许您存储"解析器"。由这些函数在一个变量中返回,并多次使用它。或者,换句话说,除了问题中的函数定义,你还可以写
let parser = tag("Hello");
,然后像调用函数一样调用parser
。
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
}
游乐场