当前位置: 首页 > 知识库问答 >
问题:

在Rust中,如何定义将Vec转换为Vec

上官淮晨
2023-03-14

我需要这样的东西:

fn my_convert<T, U>(v: &Vec<U>)->Vec<T>{
    v.iter().map(|&t|t).collect()
}

当然,我认为只有内置数字类型的向量才能传递给函数。

编译器告诉我,我需要为Vec提供FromIterator的trait

traitstd::iter::from迭代器

然后,我补充道

impl<T, U> std::iter::FromIterator<U> for Vec<T>{
    fn from_iter<I>(iter:I)->Self where I: IntoIterator<Item=U>{
        Vec::<T>::new()    // just for test
    }
}

traitstd::iter::from迭代器的冲突实现

众所周知,在C语言中,这种转换是直接的、直观的。我是铁锈的初学者。我不知道如何定义上述函数。我甚至不知道这是否可以在锈菌中实现,因为泛型类型的特征非常复杂。

谢谢


共有1个答案

丌官招
2023-03-14
匿名用户

来自的锈迹特征是你的一般目的“如何从A到B”。如果有一个合理的方法从UT,那么T:from

fn my_convert<T, U>(v: Vec<U>) -> Vec<T>
where T: From<U> {
  v.into_iter().map(T::from).collect()
}

请注意,我确实拥有v向量的所有权。From::From函数使用它的参数,所以我们也应该使用向量。你可以编写这个函数的一个完全通用的版本,它可以与任意迭代器一起工作,这样就更容易在拥有数据的迭代器和只借用数据的迭代器之间来回切换。

fn my_convert1<T, U, I>(v: I) -> Vec<T>
where T: From<U>,
      I: Iterator<Item=U> {
  v.map(T::from).collect()
}

但在这一点上,您最好直接编写v.map(T::from). Collection(),任何相当熟练的Rust程序员都会立即知道您在做什么。

这里有一点需要注意,因为你已经提到你是一名C程序员。在C语言中,模板函数可以简单地按原样编写,然后,当调用方实例化模板函数的一个版本时,编译器会检查它是否正常。因此,您在OP中提出的函数运行良好,因为编译器只在调用它时检查它。Rust(事实上,大多数带有泛型的语言)不是这样的。

另一方面,在Rust中,当您编写my_convert函数时,Rust会检查所有类型是否对齐。你不能编写一个只在某些时间有效的函数。如果你说my_convert适用于所有TU,那么它最好适用于所有这些,Rust的类型检查器和借阅检查器将立即验证这一点。如果没有,那么你最好像我上面做的那样,限制类型签名。如果你曾经使用过C 20,你可以认为特质在某种程度上类似于C 20中的“概念”特性。

 类似资料: