3 回答

TA貢獻1802條經驗 獲得超4個贊
的任一箱提供Either類型。如果兩個Either都是迭代器,則Either:也是
extern crate either;
use either::Either;
use std::iter;
fn main() {
let x: Option<i64> = None;
// Repeat x 5 times if present, otherwise count from 1 to 5
let iter = match x {
None => Either::Left(1..5),
Some(x) => Either::Right(iter::repeat(x).take(5)),
};
for i in iter {
println!("{}", i);
}
}
像先前的答案一樣,這仍然會占用每種具體類型的堆??臻g。但是,您不需要為每個具體值使用單獨的變量。
也可以從函數返回此類型,這與trait對象引用不同。與盒裝特征對象相比,無論選擇哪種具體類型,它都將始終在堆棧上使用固定大小。
您還會在其他地方找到這種類型(或語義等效),例如 futures::Either

TA貢獻1816條經驗 獲得超6個贊
您需要引用一個特征:
use std::iter;
fn main() {
let mut a;
let mut b;
let x: Option<i64> = None;
// Repeat x 5 times if present, otherwise count from 1 to 5
let iter: &mut Iterator<Item = i64> = match x {
None => {
a = 1..5;
&mut a
}
Some(x) => {
b = iter::repeat(x).take(5);
&mut b
}
};
for i in iter {
println!("{}", i);
}
}
該解決方案的主要缺點是,您必須為每種具體類型分配堆??臻g。這也意味著每種類型的變量。一件好事是只需要初始化使用的類型。
相同的想法但需要堆分配的是使用裝箱的特征對象:
use std::iter;
fn main() {
let x: Option<i64> = None;
// Repeat x 5 times if present, otherwise count from 1 to 5
let iter: Box<Iterator<Item = i64>> = match x {
None => Box::new(1..5),
Some(x) => Box::new(iter::repeat(x).take(5)),
};
for i in iter {
println!("{}", i);
}
}
當您要從函數返回迭代器時,這最有用。占用的堆??臻g是單個指針,并且只會分配所需的堆空間。

TA貢獻1811條經驗 獲得超4個贊
就個人而言,Either我通常更喜歡創建一系列Option<Iterator>鏈接在一起的價值觀,而不是使用。像這樣:
操場
use std::iter;
fn main() {
let x: Option<i64> = None;
// Repeat x 5 times if present, otherwise count from 1 to 5
for i in pick(x) {
println!("{}", i);
}
}
fn pick(opt_x: Option<i64>) -> impl Iterator<Item = i64> {
let iter_a = if let None = opt_x {
Some(1..5)
} else {
None
};
let iter_b = if let Some(x) = opt_x {
Some(iter::repeat(x).take(5))
} else {
None
};
iter_a.into_iter().flatten().chain(iter_b.into_iter().flatten())
}
與使用相比Either,它不那么明顯,但是它避免了使用其他板條箱,有時效果非常好。
- 3 回答
- 0 關注
- 573 瀏覽
相關問題推薦
添加回答
舉報