rust - 匹配返回迭代器的武器?

标签 rust matching traits trait-objects

我有一些代码尝试运行匹配,其中每个分支都可以返回不同的类型,但是所有这些类型都实现了 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/

相关文章:

closures - 为什么嵌套迭代器闭包不会从外部范围复制值

algorithm - 如何将二分匹配转换为独立集

c++ - 哪种方式更好地定义类型特征或行为?

rust - 如何满足 Iterator trait bound 以便在这里使用 Rayon?

rust - actix_web 中间件 ErrorHandlers 在 ServiceResponse 中返回错误消息

rust - Rust 中的动态类型实体组件系统

javascript - 如何在 JavaScript 中将用户输入与数组数据进行匹配

sql-server - LIKE 在 SQL 中不起作用

rust - 为什么我需要在 “cover”中使用 `impl ForeignTrait<LocalType> for T` T [E0210]

scala - 在Scala中,父特征是否可以调用子类中实现的方法?