在Rust中,我们可以对各种集合使用.iter()来创建一个不属于自己的迭代器,该迭代器返回对Vec这样的集合的引用.我们还可以使用.into_iter()创建一个使用迭代器,然后返回移出集合的值..iter()没有与.into_iter()相同的特征,但我们可以通过对集合的引用调用.into_iter()来实现相同的功能.

例如,此函数可以很好地编译:

fn test_vec(vec: Vec<i32>) {
    let i1 = (&vec).into_iter(); // create a non-owning iterator
    let i2 = (&vec).into_iter(); // create another one

    let i3 = vec.into_iter(); // create an owning iterator which consumes the collection

    // no more non-owning iterators can be created
}

我想使此函数成为泛型函数.我希望它不仅接受I32的VEC,还接受碰巧实现IntoIterator&lt;Item=I32&>的任何其他I32集合.

这样做似乎很简单,但是下面的泛型函数不再编译.

fn test_generic<T: IntoIterator<Item = i32>>(vec: T) {
    let i1 = (&vec).into_iter(); // create a non-owning iterator
    let i2 = (&vec).into_iter(); // create another one

    let i3 = vec.into_iter(); // create an owning iterator which consumes the collection

    // no more non-owning iterators can be created
}

编译失败,出现以下错误:

    |     let i1 = (&vec).into_iter(); // create a non-owning iterator
    |              ^^^^^^^-----------
    |              |      |
    |              |      value moved due to this method call
    |              move occurs because value has type `T`, which does not implement the `Copy` trait
    |
note: this function takes ownership of the receiver `self`, which moves value

我不太理解错误的这一部分:

 move occurs because value has type `T`, which does not implement the `Copy` 

我不是要复制T类型的值,我是要复制&T类型的值,即对T的引用,而不是T本身.我认为您可以复制不变的引用而不会出现问题.为什么需要T而不是&amp;T来实施复制?

推荐答案

在泛型函数的上下文中,该类型的唯一内容来自边界.如果指定T: IntoIterator<Item = i32>,则只有T实现IntoIterator,&T不实现.当然,Autoderef会起作用,取消引用的引用,但试图将值移出引用.

如果要指定&T实现IntoIterator,方法如下:

fn test_generic<T>(vec: T)
where
    T: IntoIterator<Item = i32>,
    for<'a> &'a T: IntoIterator<Item = &'a i32>,
{

Rust相关问答推荐

两个相关特征的冲突实现错误

无法理解铁 rust &S错误处理

制作一片连续整数的惯用Rust 方法?

闭包不会发送,即使它只捕获发送变量

正则表达式中的重叠匹配?(铁 rust 正则式发动机)

完全匹配包含大小写的整数范围(&Q;)

写入引用会更新基础值,但引用会打印意外的值

如何使用reqwest进行异步请求?

Tokio';s io::用Cursor拆分<;Vec<;u8>>;赢得';t get the full writted data

为什么将易错函数的泛型结果作为泛型参数传递 infer ()?不应该是暧昧的吗?

write_buffer 不写入缓冲区而是输出零 WGPU

‘&T as *const T as *mut T’ 在 ‘static mut’ 项目中合适吗?

如何在 Emacs Elisp 中获得类似格式化的 LSP?

rust 中不同类型的工厂函数

如何连接 Rust 中的相邻切片

如何为返回正确类型的枚举实现 get 方法?

Iterator::collect如何进行转换?

为什么 Rust 标准库同时为 Thing 和 &Thing 实现特征?

基于名称是否存在的条件编译

为什么我不能将元素写入 Rust 数组中移动的位置,但我可以在元组中完成