如何在堆栈上创建按值迭代器

时间:2018-10-02 09:39:10

标签: iterator rust

我可以在堆中创建一个消耗迭代器:

amo.timer.LOOP.ALT_1 = 61;

我还可以在借用元素的堆栈上创建一个迭代器:

vec![1, 10, 100].into_iter()

但是如果我这样写:

[1, 10, 100].iter()

这不是一个消耗迭代器,因为[1, 10, 100].into_iter() 不存在:[T; _]::into_iter仅针对借用版本(也称为切片)实现。是否有一种简单的方法(最好是在IntoIterator lib中)在堆栈上创建使用迭代器?


我知道std是可以做到的,但这要求物品是可克隆的。

3 个答案:

答案 0 :(得分:5)

  

是否有一种简单的方法(最好是在std库中)在堆栈上创建消耗迭代器?

否。

  

是否有一种简单的方法(最好是在std库中)在堆栈上创建消耗迭代器?

是的。使用诸如stacksmallvec之类的板条箱,它们提供实现IntoIterator的数组类型。

答案 1 :(得分:2)

您可以拥有一个宏,该宏将这些值包装在once迭代器中,并将它们chains包裹在一起:

macro_rules! value_iter {
    () => {
        std::iter::empty()
    };
    ($v: expr, $( $rest: expr ), +) => {
        std::iter::once($v).chain(
            value_iter!($($rest),*)
        )
    };
    ($v: expr) => {
        std::iter::once($v)
    };
}

使用:

#[derive(Debug, PartialEq)]
struct Foo;

let it = value_iter![Foo, Foo, Foo];

let all: Vec<_> = it.collect();
assert_eq!(all, vec![Foo, Foo, Foo]);

一个已知的缺点是迭代器将不是精确大小的迭代器,因此编译器可能会错过一些明显的优化。

Playground

答案 2 :(得分:0)

非常丑陋,但在技术上可行:

for s in [
    Some(String::from("hello")),
    Some(String::from("goodbye"))
].iter_mut().map(|option| option.take().unwrap()) {
    let s: String = s;
    println!("{}", s);
}

也许您可以定义一个可以更漂亮地实现此目标的宏。