rust 将类型A的向量转换为类型B,其中A可转换为B

irtuqstp  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(166)

我正在学习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 TT(在这个例子中,我相信自从我定义了From特征之后,它就被定义了)。

dw1jzc5e

dw1jzc5e1#

你忽略了一个很简单但很容易忽略的事实:如果你有一个From<T> for U实现,你就自动有了一个Into<U> for T实现,* 但相反的情况不成立 *。因此,如果你需要泛型T: Into<B>(这是正确的做法,因为它比B: From<T>更通用),你需要使用.into()而不是B::from()

impl B {
    pub fn from_many<T: Into<B> + Clone>(v: Vec<T>) -> Self {
        B { x: v.iter().map(|e| e.clone().into().x).collect::<Vec<String>>().join(" ") }
    }
}

另一个不相关的问题是,既然你有一个自己拥有的Vec<T>,你就可以使用into_iter(),而不需要使用.clone()

impl B {
    pub fn from_many<T: Into<B>>(v: Vec<T>) -> Self {
        B { x: v.into_iter().map(|e| e.into().x).collect::<Vec<String>>().join(" ") }
    }
}

相关问题