首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在堆栈上创建一个值迭代器?

如何在堆栈上创建一个值迭代器?
EN

Stack Overflow用户
提问于 2018-10-02 09:39:09
回答 2查看 131关注 0票数 4

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

代码语言:javascript
复制
vec![1, 10, 100].into_iter()

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

代码语言:javascript
复制
[1, 10, 100].iter()

但如果我写这个:

代码语言:javascript
复制
[1, 10, 100].into_iter()

这不是一个消耗迭代器,因为[T; _]::into_iter不存在:IntoIterator只是为借来的版本(也就是片)实现的。有没有一种简单的方法(最好在std库中)在堆栈上创建一个消耗的迭代器?

我知道[1, 10, 100].iter().cloned()是可以完成的,但这要求项目是可复制的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-20 09:47:41

您可以拥有一个宏,它将once迭代器中的值包装在一起,并将它们封装在链子中:

代码语言:javascript
复制
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)
    };
}

使用:

代码语言:javascript
复制
#[derive(Debug, PartialEq)]
struct Foo;

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

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

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

游乐场

票数 2
EN

Stack Overflow用户

发布于 2018-10-02 19:24:35

很丑,但技术上有效:

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

您可以使用一个宏以更漂亮的方式实现这一点:

代码语言:javascript
复制
macro_rules! iter {
    [ $( $item:expr ),+ ] => {{
        [ $( Some($item), )+ ]
        .iter_mut()
        .map(|o| o.take().unwrap())
    }};
    // Rule to allow a trailing comma:
    [ $( $item:expr, )+ ] => {{
        iter![ $( $item ),+ ]
    }};
}

fn main() {
    for s in iter![String::from("hello"), String::from("goodbye")] {
        println!("{}", s);
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52605781

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档