1

我是 Rust 初学者,正在编写一个可以解析冒号分隔KEY: VALUE的行的 nom 解析器。我制作了一个可以解析键值对的基本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'd 版本,我假设它map_res返回不同的值,可能具有不同的生命周期。

我想我可能不得不更改kv解析器的生命周期定义,但我完全不知道如何选择/选择哪些。

4

0 回答 0