如何让函数 return 成为具有相同项目类型的两个迭代器之一?
How to have a function return one of two iterators with same item type?
following 无法编译,因为两个迭代器具有不同的签名。但是,两个迭代器 return 具有相同的项目类型并且在概念上表现相同。
fn f(flag: bool) -> impl Iterator<Item = u8> {
if flag {
(0..8).into_iter()
} else {
(0..8).into_iter().map(|x| x + 1)
}
}
我想编写一个函数,从算法的不同变体生成 returns 个项目,这些项目由我传递给函数的值选择。我怎样才能做到这一点?
最终,我需要在 no_std
环境中使用它。这可能吗?
我不知道有任何 built-in 方法可以做到这一点,但实施有效的方法并不过分棘手。
您需要的是一种既可以表示 (0..8).into_iter()
结果的类型——它是 Iterator<Item=u8>
的一种,也是 (0..8).into_iter().map(|x| x+1)
的一种。如果您不想使用 Boxed 特征,典型的选择是创建一个有两个选项的枚举。
然后,如果您在枚举上实现 Iterator<Item=u8>
,您就完成了。
这样的枚举可能如下所示:
pub enum EitherIter<AIterType, BIterType> {
A(AIterType),
B(BIterType),
}
impl<AIterType, BIterType> Iterator for EitherIter<AIterType, BIterType>
where
AIterType: Iterator,
BIterType: Iterator<Item = AIterType::Item>,
{
type Item = AIterType::Item;
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
match self {
EitherIter::A(it) => it.next(),
EitherIter::B(it) => it.next(),
}
}
}
然后使用它包装每个 return 类型中的一种类型。
pub fn f(flag: bool) -> impl Iterator<Item = u8> {
if flag {
EitherIter::A((0..8).into_iter())
} else {
EitherIter::B((0..8).into_iter().map(|x| x + 1))
}
}
您可以在 playground 中试用。
following 无法编译,因为两个迭代器具有不同的签名。但是,两个迭代器 return 具有相同的项目类型并且在概念上表现相同。
fn f(flag: bool) -> impl Iterator<Item = u8> {
if flag {
(0..8).into_iter()
} else {
(0..8).into_iter().map(|x| x + 1)
}
}
我想编写一个函数,从算法的不同变体生成 returns 个项目,这些项目由我传递给函数的值选择。我怎样才能做到这一点?
最终,我需要在 no_std
环境中使用它。这可能吗?
我不知道有任何 built-in 方法可以做到这一点,但实施有效的方法并不过分棘手。
您需要的是一种既可以表示 (0..8).into_iter()
结果的类型——它是 Iterator<Item=u8>
的一种,也是 (0..8).into_iter().map(|x| x+1)
的一种。如果您不想使用 Boxed 特征,典型的选择是创建一个有两个选项的枚举。
然后,如果您在枚举上实现 Iterator<Item=u8>
,您就完成了。
这样的枚举可能如下所示:
pub enum EitherIter<AIterType, BIterType> {
A(AIterType),
B(BIterType),
}
impl<AIterType, BIterType> Iterator for EitherIter<AIterType, BIterType>
where
AIterType: Iterator,
BIterType: Iterator<Item = AIterType::Item>,
{
type Item = AIterType::Item;
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
match self {
EitherIter::A(it) => it.next(),
EitherIter::B(it) => it.next(),
}
}
}
然后使用它包装每个 return 类型中的一种类型。
pub fn f(flag: bool) -> impl Iterator<Item = u8> {
if flag {
EitherIter::A((0..8).into_iter())
} else {
EitherIter::B((0..8).into_iter().map(|x| x + 1))
}
}
您可以在 playground 中试用。