Rust:通过克隆将iter of &T转换为iter of T

kokeuurv  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(85)

如何通过克隆将返回&T的迭代器转换为返回T的迭代器?
最小可重现示例:
考虑一个由ndarray提供的迭代器,它返回&Value对象。定义一个函数,它返回Value对象的迭代器。

#[derive(Clone)]
struct Value;

pub trait IterValue<I: Iterator<Item = Value>> {
    fn iter_value(&self) -> I;
}

impl<'cellref, 'cell: 'cellref>
    IterValue<
        std::iter::Map<
            ndarray::iter::Iter<'cellref, Value, ndarray::Dim<[usize; 1]>>,
            fn(&Value) -> Value,
        >,
    > for ndarray::Array1<Value>
{
    fn iter_value(
        &self,
    ) -> std::iter::Map<
        ndarray::iter::Iter<'cellref, Value, ndarray::Dim<[usize; 1]>>,
        fn(&Value) -> Value,
    > {
        self.iter().map(|val| val.clone())
    }
}

// ... impl for ndarrays of other dimensions ...
// ... and possibly Array<T> for other T that will be converted to Value ...

字符串
错误输出:

error: lifetime may not live long enough
  --> src\lib.rs:22:9
   |
8  | impl<'cellref, 'cell: 'cellref>
   |      -------- lifetime `'cellref` defined here
...
17 |         &self,
   |         - let's call the lifetime of this reference `'1`
...
22 |         self.iter().map(|val| val.clone())
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method was supposed to return data with lifetime `'cellref` but it is returning data with lifetime `'1`
   |
help: consider adding 'move' keyword before the nested closure
   |
22 |         self.iter().map(move |val| val.clone())
   |                         ++++

fsi0uk1n

fsi0uk1n1#

你的代码对于一个已经解决的问题来说是多余的。
每个Iterator<Item = &T>都可以通过.cloned()转换为Iterator<Item = T>。(当然,如果TClone
就像这样:

#[derive(Clone, Debug)]
struct Value(i32);

fn produce_reference_iter<'a>() -> impl Iterator<Item = &'a Value> {
    const data: [Value; 3] = [Value(1), Value(2), Value(3)];
    data.iter()
}

fn consume_owned_iter(iter: impl Iterator<Item = Value>) {
    println!("Iter data: {:?}", iter.collect::<Vec<_>>());
}

fn main() {
    let iter_refs /* Iterator<Item = &Value> */ = produce_reference_iter();
    let iter_owned /* Iterator<Item = Value> */ = iter_refs.cloned();
    consume_owned_iter(iter_owned);
}

个字符

相关问题