我想做这样的事情:
enum MyEnum {
Foo(Vec<Stuff>),
// ...
}
impl MyEnum {
fn do_sth(&self) -> Result<Bar, E> {
match *self {
MyEnum::Foo(ref vec) => {
let (a, b): (Vec<A>, Vec<B>) = vec
.iter()
.map(|thing| thing.make_a_tuple(arg)) // returns Result<(A, B), E>
.collect::<Result<_, _>>()? // stop on first error
.unzip();
// use a and b
}
// other cases
}
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
这无法与error: the type of this value must be known in this context. 通过反复试验,我让它像这样编译
fn do_sth(&self) -> Result<Bar, E> {
match *self {
MyEnum::Foo(ref vec) => {
let (a, b): (Vec<A>, Vec<B>) = vec
.iter()
.map(|thing| thing.make_a_tuple(arg))
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.unzip();
// use a and b
}
// other cases
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我想避免不必要的Vec<(A, B)>.
是否可以在没有中间分配的情况下做到这一点?我确信我可以自己用循环来做到这一点,但我更愿意学习 Rusty 的方式。
我经常遇到Results 迭代器的此类问题,因此我在名为 的标准库中添加了一个(私有)辅助类型ResultShunt。这为sSum和sProductResult的实现提供了动力。
我还将它提交给 itertools,以便可以重用:
use itertools; // 0.10.1
fn main() {
let iter_source: Vec<Result<(i32, i32), bool>> = vec![Ok((1, 2)), Err(false), Ok((3, 4))];
let z = itertools::process_results(iter_source, |iter| iter.unzip::<_, _, Vec<_>, Vec<_>>());
println!("{:?}", z);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
246 次 |
| 最近记录: |