我有一些代码尝试运行匹配,其中每个分支都可以返回不同的类型,但是所有这些类型都实现了 Iterator<Item=usize>
强>。
let found: Iterator<Item = usize> = match requirements {
Requirements::A => MatchingAs { ainternals: [] },
Requirements::B => MatchingBs { binternals: [] },
Requirements::C => MatchingCs { cinternals: [] },
};
return found.any(|m| m == 1)
... 其中 MatchingAs
, MatchingBs
, 和 MatchingCs
所有impl
std::iter::Iterator<Item = usize>
.
我碰壁了 Iterator
未调整大小:
| the trait `std::marker::Sized` is not implemented for `std::iter::Iterator<Item=usize>`
是否有一种好的方法让匹配臂返回具有共享特征的对象,然后(仅)依赖于该特征来处理结果?
最佳答案
当你想要返回不是 Sized
的东西时的第一个 react , 是 Box
它(又名,把它放在堆上,返回一个指针):
let found: Box<Iterator<Item = usize>> = match requirements {
Requirements::A => Box::new(MatchingAs { ainternals: [] }),
Requirements::B => Box::new(MatchingBs { binternals: [] }),
Requirements::C => Box::new(MatchingCs { cinternals: [] }),
};
found.any(|m| m == 1)
这还不够,因为现在 match
会提示你返回不同的类型:Box<MatchingAs>
, Box<MatchingBs>
, ...
然而,Box<Concrete>
可以转换为 Box<Trait>
每当有impl Trait for Concrete
,所以:
let found = match requirements {
Requirements::A => Box::new(MatchingAs { ainternals: [] }) as Box<Iterator<Item = usize>>,
Requirements::B => Box::new(MatchingBs { binternals: [] }) as Box<Iterator<Item = usize>>,
Requirements::C => Box::new(MatchingCs { cinternals: [] }) as Box<Iterator<Item = usize>>,
};
found.any(|m| m == 1)
不过,有一种无需分配的解决方案:使用泛型。
fn search<T: Iterator<Item = usize>>(t: T) -> bool {
t.any(|m| m == 1)
}
然后将该函数应用于 match
的每个分支:
match requirements {
Requirements::A => search(MatchingAs {ainternals: []}),
Requirements::B => search(MatchingBs {binternals: []}),
Requirements::C => search(MatchingCs {cinternals: []}),
}
权衡是它有点接近回调 hell ,有点间接流。
关于rust - 匹配返回迭代器的武器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41704481/