如何为解析函数指定类型?

  • 本文关键字:类型 函数 rust nom
  • 更新时间 :
  • 英文 :


我试图用以下函数解析缩进级别:

fn get_indent_level(input: &str) -> usize {
let (_, result) = many0_count(alt((tag("L_ "), tag("|  "), tag("   "))))(input).unwrap_or_default();
result
}

我得到了这个编译错误:

error[E0283]: type annotations needed
--> srclib.rs:149:23
|
149 |     let (_, result) = many0_count(alt((tag("L_ "), tag("|  "), tag("   "))))(input).unwrap_or_default();
|                       ^^^^^^^^^^^ cannot infer type for type parameter `E` declared on the function `many0_count`
| 
::: C:Usersuser1.cargoregistrysrcgithub.com-xxxxxxxxxxxxxxxnom-6.2.1srcmultimod.rs:486:6
|
486 |   E: ParseError<I>,
|      ------------- required by this bound in `many0_count`
|
= note: cannot satisfy `_: ParseError<&str>`
help: consider specifying the type arguments in the function call
|
149 |     let (_, result) = many0_count::<I, O, E, F>(alt((tag("L_ "), tag("|  "), tag("   "))))(input).unwrap_or_default();
|                                  ^^^^^^^^^^^^^^

当我像这样添加类型时:

fn get_indent_level(input: &str) -> usize {
let (_, result) = many0_count::<&str, usize, nom::error::ErrorKind, &str>(alt((tag("L_ "), tag("|  "), tag("   "))))(input).unwrap_or_default();
result
}

我得到这个新的错误:

error[E0277]: the trait bound `nom::error::ErrorKind: ParseError<&str>` is not satisfied
--> srclib.rs:149:23
|
149 |     let (_, result) = many0_count::<&str, usize, nom::error::ErrorKind, &str>(alt((tag("L_ "), tag("|  "), tag("   "))))(input).unwrap_or...
|                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ParseError<&str>` is not implemented for `nom::error::ErrorKind`
| 
::: C:Usersuser1.cargoregistrysrcgithub.com-xxxxxxxxxxnom-6.2.1srcmultimod.rs:486:6
|
486 |   E: ParseError<I>,
|      ------------- required by this bound in `many0_count`

添加类型和解决问题的正确方法是什么?

您只需要指定错误类型,因为nom可以返回不同的错误类型,编译器无法推断它,因为错误不会在任何地方使用。您可以使用_语法让编译器推断出其余的已知类型。

最简单的方法是在IResult类型上指定类型,因为它需要的类型比many0_count()少:

fn get_indent_level(input: &str) -> usize {
let result: IResult<_, _, nom::error::Error<_>> =
many0_count(alt((
tag("L_ "), 
tag("|  "),
tag("   ")
)))(input);
result.map(|(_, x)| x).unwrap_or_default()
}

这样你只需要提供3种类型,其中2种是已知的(输入-&str;和结果-usize),所以你可以让编译器使用_语法推断它们,并手动只写错误类型。

相关内容

  • 没有找到相关文章

最新更新