我是Rust的初学者,他写了一个nom解析器,可以解析用冒号分隔的KEY: VALUE
的行。我用kv
做了一个基础named_args
解析器,可以解析键值对:
named_args!(kv<'a>(key: &'a str)<&'a str, &'a str>,
do_parse!(
tag_s!(key) >>
tag_s!(":") >>
space0 >>
value: rest >>
(value)
)
);
我把生命周期放在这里,以取悦编译器。
我从中获得了这两个解析器:
named!(name<&str,&str>,
call!(kv, "NAME")
);
named!(get_dimension<&str, i64>,
map_res!(call!(kv, "DIMENSION"), str::parse::<i64>)
);
为了测试这些,我正在编写一个通用包装器,该包装器使用KEY: {YOUR_VALUE}
字符串调用其中一个函数,并期望返回YOUR_VALUE
:
fn test_kv<G: Display + Debug + PartialEq>(
kvfunc: fn(&str) -> Result<(&str, G), Err<&str>>,
key: &str,
value: G,
) {
assert_eq!(kvfunc(&format!("{}: {}", key, value)), Ok(("", value)));
}
这很好:
#[test]
fn test_dimension() {
test_kv(get_dimension, "DIMENSION", 8)
}
但不能使用name
解析器:
#[test]
fn test_name() {
test_kv(name, "NAME", "some_name")
}
编译器给我:
71 | test_kv(name, "NAME", "some_name")
| ^^^^ expected concrete lifetime, found bound lifetime parameter
|
= note: expected type `for<'r> fn(&'r str) -> std::result::Result<(&'r str, _), nom::Err<&'r str>>`
found type `for<'r> fn(&'r str) -> std::result::Result<(&'r str, &'r str), nom::Err<&'r str>> {name}`
这使我感到困惑。 Result<&str, &str>
是否不适合Result<&str, _>
?
由于它可以与map_res
版一起使用,因此我假设map_res
返回的值可能不同,也可能具有不同的生存期。
我认为我可能不得不更改我的kv
解析器的生存期定义,但是我完全迷失了选择方式/选择哪种方式。