使用 nom 解析时,无法推断函数“tuple”上声明的类型参数“I”的类型

Whi*_*ork 3 rust nom

我正在尝试使用nomtuple功能。该文档提供了以下示例:

use nom::sequence::tuple;
use nom::character::complete::{alpha1, digit1};
let parser = tuple((alpha1, digit1, alpha1));
Run Code Online (Sandbox Code Playgroud)

当我尝试时,出现编译错误:

    error[E0283]: type annotations needed
   --> src/main.rs:20:18
    |
20  |     let parser = tuple((alpha1, digit1, alpha1));
    |         ------   ^^^^^ cannot infer type for type parameter `I` declared on the function `tuple`
    |         |
    |         consider giving `parser` a type
    | 
Run Code Online (Sandbox Code Playgroud)

如果我想为变量添加一个类型,它会是什么?我知道它必须是 的某种变体FnMut,但我不确定它到底是如何工作的。

Cargo.toml

[dependencies]
nom = ">=5.0"
Run Code Online (Sandbox Code Playgroud)

Sve*_*ach 5

类型推断需要足够的信息来实际推断类型。您可以通过复制文档中的完整示例来提供所需的信息,包括两个assert_eq!()语句:

use nom::sequence::tuple;
use nom::character::complete::{alpha1, digit1};
let mut parser = tuple((alpha1, digit1, alpha1));

assert_eq!(parser("abc123def"), Ok(("", ("abc", "123", "def"))));
assert_eq!(parser("123def"), Err(Err::Error(("123def", ErrorKind::Alpha))));
Run Code Online (Sandbox Code Playgroud)

额外的调用向编译器通知 所返回函数的参数和返回类型tuple(),这反过来又为编译器提供了足够的信息来推断调用的所有类型参数tuple()

或者,您可以显式地将类型参数传递给函数tuple()。以下是 Rust 需要提供的最少信息,以便能够推断所有类型:

let _parser = tuple::<&str, _, (_, _), _>((alpha1, digit1, alpha1));
Run Code Online (Sandbox Code Playgroud)

请注意,类型推断在 Rust 中如何工作的详细信息不是语言规范的一部分,并且可能在 Rust 的未来版本中发生变化。虽然 Rust 具有相当强的向后兼容性保证,但在升级到新版本时,有时可能需要向代码添加一些类型注释。