我正在学习rust,我想做的最基本的事情之一是取一个同质类型A
的向量,它可以转换为另一个类型B
(因为实现了From<>
,所以我们可以使用.into()
)。当我尝试运行下面的代码时,我得到了以下结果:
struct A {
x: String
}
struct B {
x: String
}
impl From<A> for B {
fn from(a: A) -> Self {
B { x: a.x }
}
}
impl B {
pub fn from_many<T: Into<B> + Clone>(v: Vec<T>) -> Self {
B { x: v.iter().map(|e| B::from(e.clone()).x).collect::<Vec<String>>().join(" ") }
}
}
fn main() {
...
}
我得到了:
error[E0277]: the trait bound `B: From<T>` is not satisfied
--> src/main.rs:17:41
|
17 | B { x: v.iter().map(|e| B::from(e.clone()).x).collect::<Vec<String>>().join(" ") }
| ------- ^^^^^^^^^ the trait `From<T>` is not implemented for `B`
| |
| required by a bound introduced by this call
|
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
15 | impl B where B: From<T> {
| ++++++++++++++++
我最初尝试不使用clone()
,但认为它不接受引用:
...
impl B {
pub fn from_many<T: Into<B>>(v: Vec<T>) -> Self {
B { x: v.iter().map(|e| B::from(e).x).collect::<Vec<String>>().join(" ") }
}
}
...
其产生:
error[E0277]: the trait bound `B: From<&T>` is not satisfied
--> src/main.rs:17:41
|
17 | B { x: v.iter().map(|e| B::from(e).x).collect::<Vec<String>>().join(" ") }
| ------- ^ the trait `From<&T>` is not implemented for `B`
| |
| required by a bound introduced by this call
|
= help: the trait `From<A>` is implemented for `B`
这里我并不是要一个任意的T
,我是要一个定义了Into<B> for T
的T
(在这个例子中,我相信自从我定义了From
特征之后,它就被定义了)。
1条答案
按热度按时间dw1jzc5e1#
你忽略了一个很简单但很容易忽略的事实:如果你有一个
From<T> for U
实现,你就自动有了一个Into<U> for T
实现,* 但相反的情况不成立 *。因此,如果你需要泛型T: Into<B>
(这是正确的做法,因为它比B: From<T>
更通用),你需要使用.into()
而不是B::from()
:另一个不相关的问题是,既然你有一个自己拥有的
Vec<T>
,你就可以使用into_iter()
,而不需要使用.clone()
: