代码之家  ›  专栏  ›  技术社区  ›  OneRaynyDay

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

  •  0
  • OneRaynyDay  · 技术社区  · 3 年前

    我正在学习铁锈,我想做的最基本的事情之一是取一个同质类型的向量 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 给,我要 T 它有 Into<B> for T 定义的(在这种情况下,我相信它是定义的,因为我定义了 From 性状)。我在这里做了什么蠢事吗?

    1 回复  |  直到 3 年前
        1
  •  4
  •   Chayim Friedman    3 年前

    你错过了一个非常简单但容易错过的事实:如果你有 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(" ") }
        }
    }
    
    推荐文章