【问题标题】:Convert vector of type A to type B where A is convertible to B将 A 类型的向量转换为 B 类型,其中 A 可转换为 B
【发布时间】:2022-11-07 14:17:08
【问题描述】:

我正在学习 rust,我想做的最基本的事情之一就是采用一个同质类型的向量 A,它可以转换为另一种类型 B(因为实现了 From<>,因此我们可以使用 @ 987654324@)。当我尝试运行以下内容时,我得到以下信息:

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&lt;B&gt; for T(在这种情况下,我相信它已经定义了,因为我定义了From 特征)。我在这里做了什么蠢事吗?

【问题讨论】:

    标签: rust


    【解决方案1】:

    你错过了一个非常简单但容易错过的事实:如果你有一个 From&lt;T&gt; for U 实现,你会自动拥有一个 Into&lt;U&gt; for T 实现,但事实并非如此.因此,如果通过泛型您需要T: Into&lt;B&gt;(这是正确的做法,因为它比B: From&lt;T&gt; 更通用),您需要使用.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&lt;T&gt;,因此您可以使用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(" ") }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多