假设我有一个结构体调用SevenDigits
,顾名思义,它是一个由7位且只有7位数字组成的类型。
struct SevenDigits([u8; 7]);
我已经为三种类型实现了std::convert::TryFrom
特征:&str
、Vector
和u32
。例如,对于u32
的实现,它是:
impl TryFrom<u32> for ICDigits {
type Error = &'static str;
fn try_from(value: u32) -> Result<Self, Self::Error> {
let mut digits = [0; 7];
let mut remaining = value;
for i in (0..7).rev() {
let digit = remaining % 10;
remaining /= 10;
digits[i] = digit as u8;
}
if remaining > 0 {
Err("Number is too large to fit in an array of 7 digits")
} else {
Ok(ICDigits(digits))
}
}
}
假设现在我想实现一个方法pub fn try_parse<T: TryInto<SevenDigits>>(value: T) -> Result<Self, &'static str> {
,其中T
是实现TryInto<SevenDigits>
trait的任何泛型类型。
这个函数的自然实现是:
pub fn try_parse<T: TryInto<SevenDigits>>(value: T) -> Result<Self, &'static str> {
TryFrom::try_from(value)
}
}
在cargo check
上,这给了我两个错误:
error[E0271]: type mismatch resolving `<SevenDigitsas TryFrom<T>>::Error == &str`
--> src/digits.rs:25:5
|
25 | TryFrom::try_from(value)
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Infallible`, found `&str`
error[E0277]: the trait bound `SevenDigits: From<T>` is not satisfied
--> src/digits.rs:25:5
|
25 | TryFrom::try_from(value)
| ^^^^^^^^^^^^^^^^^ the trait `From<T>` is not implemented for `SevenDigits`
|
= note: required because of the requirements on the impl of `Into<SevenDigits>` for `T`
= note: required because of the requirements on the impl of `TryFrom<T>` for `ICDigits`
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
9 | impl SevenDigits where SevenDigits: From<T> {
| +++++++++++++++++++++++
错误信息令人困惑,我该如何实现这个pub fn try_parse
函数呢?
2条答案
按热度按时间fjaof16o1#
我摆弄了你的例子,直到我成功了:
Playground.
这里不能使用只有trait边界
T: TryInto<U>
的TryFrom::try_from
,因为默认实现是:impl<T, U> TryFrom<U> for T where U: Into<T>
。您必须直接使用TryInto::try_into
。实现TryFrom<T> for U
将自动实现TryInto<U> for T
,大致如下所示:这并不意味着当
T
实现TryInto<U>
时可以使用TryFrom<T>
,因为这种关系不是自反的,也就是说它只在从TryFrom
到TryInto
的一个方向上。除此之外,您只有一个类型与关联的
Error
类型不匹配。您必须显式地告诉编译器,T
的TryInto<SevenDigits>
实现返回一个&'static str
作为错误,以使其与您的函数的返回类型匹配。jogvjijk2#
所以看起来实际上有两个错误。
首先,
TryFrom
特性意味着TryInto
需要您定义一个关联的错误类型。(我假设其余的错误类型)是&'static str
。但是,泛型不知道这一点,所以实际的错误类型是T ::Error
。要解决这个问题,你可以改变函数的返回类型,或者使用match
并自己返回一个字符串错误。那么,你使用
TryInto
和TryForm
的方式就不起作用了(老实说,我不太清楚为什么)。要解决这个问题,你可以使用try_into()
或使用where
子句来定义trait绑定SevenDigits: TryFrom<T>
。下面是两个行之有效的解决方案示例:
1.更改函数签名并使用
TryInto
1.使用特征绑定和
TryFrom