我可以在堆中创建一个消耗迭代器:
vec![1, 10, 100].into_iter()我还可以在堆栈上创建一个迭代器,该迭代器借用元素:
[1, 10, 100].iter()但如果我写这个:
[1, 10, 100].into_iter()这不是一个消耗迭代器,因为[T; _]::into_iter不存在:IntoIterator只是为借来的版本(也就是片)实现的。有没有一种简单的方法(最好在std库中)在堆栈上创建一个消耗的迭代器?
我知道[1, 10, 100].iter().cloned()是可以完成的,但这要求项目是可复制的。
发布于 2019-07-20 09:47:41
您可以拥有一个宏,它将once迭代器中的值包装在一起,并将它们封装在链子中:
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]);已知的缺点是迭代器不会是精确大小的迭代器,因此编译器可能会忽略一些明显的优化。
发布于 2018-10-02 19:24:35
很丑,但技术上有效:
for s in [
Some(String::from("hello")),
Some(String::from("goodbye"))
].iter_mut().map(|option| option.take().unwrap()) {
let s: String = s;
println!("{}", s);
}您可以使用一个宏以更漂亮的方式实现这一点:
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);
}
}https://stackoverflow.com/questions/52605781
复制相似问题