Rust 编译器无法识别为结构实现的通用特征绑定
Rust compiler not recognizing a generic trait bound implemented for a struct
我正在使用 Nom, the parser combinator, to write a TOML parser. The parser function I am having trouble with parses a date time string using the chrono 板条箱。
fn offset_datetime<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, TomlValue, E> {
match DateTime::parse_from_rfc3339(input) {
ParseResult::Ok(dt) => IResult::Ok(("", TomlValue::OffsetDateTime(dt))),
ParseResult::Err(e) => {
Err(Err::Error(Error::from_error_kind(input, ErrorKind::Fail)))
}
}
}
在上面的代码中,我使用 chrono::DatetTime::parse_from_rfc3339
解析字符串切片,其中 returns 和 chrono::format::ParseResult
。然后,我匹配它以便我可以将它转换为正确的 nom::IResult
。 ParseResult::Ok
手臂没问题,但我无法为 ParseResult::Err
编写正确的代码。这是我在编译上面的代码片段时遇到的错误:
error[E0308]: mismatched types
--> src/parser.rs:193:28
|
188 | fn offset_datetime<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, TomlValue, E> {
| - this type parameter
...
193 | Err(Err::Error(Error::from_error_kind(input, ErrorKind::Fail)))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `E`, found struct `nom::error::Error`
|
= note: expected type parameter `E`
found struct `nom::error::Error<&str>`
来自 Error::from_error_kind
的 Error
是 Nom 自己的结构之一,它具有 implement ParseError
特征,正如 E
泛型指定的那样。为什么编译器不能识别这个?
每当您为函数 (offset_datetime
) 提供通用参数 (E
) 时,您就承诺该函数可以适用于 E
的所有可能类型] 可能 受其限制。您的函数签名承诺 return 一个错误类型 E
的 IResult
。但是你不那样做;相反,你 return 一个错误类型 nom::error::Error
(使用 Error::from_error_kind
)。
一种可能的修复方法是将函数签名更改为return函数体实际执行的具体错误类型:
fn offset_datetime<'a>(input: &'a str) -> IResult<&'a str, TomlValue, Error<&'a str>> {
另一种方法是更改函数体以使用签名声明的通用类型:
ParseResult::Err(e) => Err(Err::Error(E::from_error_kind(input, ErrorKind::Fail))),
请注意,不是在具体类型 nom::error::Error
上调用 from_error_kind
,而是在类型变量 E
上调用它(由于 E: ParseError
绑定)。
我不熟悉如何正确使用nom
,所以我不能告诉你哪个更合适。
我正在使用 Nom, the parser combinator, to write a TOML parser. The parser function I am having trouble with parses a date time string using the chrono 板条箱。
fn offset_datetime<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, TomlValue, E> {
match DateTime::parse_from_rfc3339(input) {
ParseResult::Ok(dt) => IResult::Ok(("", TomlValue::OffsetDateTime(dt))),
ParseResult::Err(e) => {
Err(Err::Error(Error::from_error_kind(input, ErrorKind::Fail)))
}
}
}
在上面的代码中,我使用 chrono::DatetTime::parse_from_rfc3339
解析字符串切片,其中 returns 和 chrono::format::ParseResult
。然后,我匹配它以便我可以将它转换为正确的 nom::IResult
。 ParseResult::Ok
手臂没问题,但我无法为 ParseResult::Err
编写正确的代码。这是我在编译上面的代码片段时遇到的错误:
error[E0308]: mismatched types
--> src/parser.rs:193:28
|
188 | fn offset_datetime<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, TomlValue, E> {
| - this type parameter
...
193 | Err(Err::Error(Error::from_error_kind(input, ErrorKind::Fail)))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `E`, found struct `nom::error::Error`
|
= note: expected type parameter `E`
found struct `nom::error::Error<&str>`
来自 Error::from_error_kind
的 Error
是 Nom 自己的结构之一,它具有 implement ParseError
特征,正如 E
泛型指定的那样。为什么编译器不能识别这个?
每当您为函数 (offset_datetime
) 提供通用参数 (E
) 时,您就承诺该函数可以适用于 E
的所有可能类型] 可能 受其限制。您的函数签名承诺 return 一个错误类型 E
的 IResult
。但是你不那样做;相反,你 return 一个错误类型 nom::error::Error
(使用 Error::from_error_kind
)。
一种可能的修复方法是将函数签名更改为return函数体实际执行的具体错误类型:
fn offset_datetime<'a>(input: &'a str) -> IResult<&'a str, TomlValue, Error<&'a str>> {
另一种方法是更改函数体以使用签名声明的通用类型:
ParseResult::Err(e) => Err(Err::Error(E::from_error_kind(input, ErrorKind::Fail))),
请注意,不是在具体类型 nom::error::Error
上调用 from_error_kind
,而是在类型变量 E
上调用它(由于 E: ParseError
绑定)。
我不熟悉如何正确使用nom
,所以我不能告诉你哪个更合适。