2 回答
TA贡献1805条经验 获得超10个赞
impl Trait不等同于返回接口或基类对象。这是说“我不想写我要返回的特定类型的名称”的一种方式。您仍在返回单个特定类型的值。您只是没有说哪种类型。
这些分支中的每一个都返回不同的类型,因此出现了问题。仅仅实现相同的特征是不够的。
在这种特定情况下,您可能需要的是trait对象Box<dyn RngCore>。
extern crate rand; // 0.6.5
use rand::{rngs::OsRng, thread_rng, RngCore};
fn rng() -> Box<dyn RngCore> {
match OsRng::new() {
Ok(rng) => Box::new(rng),
Err(_) => Box::new(thread_rng()),
}
}
注意:如果您使用的是Rust的旧版本,则可能需要删除dyn关键字。在当前(2015)版本的Rust中,它是可选的。
TA贡献1862条经验 获得超7个赞
DK。已经解释了为什么,但是我想提供一个替代的解决方法。
正如提到有条件迭代在几个可能的迭代器一个,您可以创建如果同时它的组件类型做一个实现特征的枚举。例如:
extern crate rand; // 0.6.5
use rand::{rngs::OsRng, thread_rng, RngCore};
fn rng() -> impl RngCore {
match OsRng::new() {
Ok(rng) => EitherRng::Left(rng),
Err(_) => EitherRng::Right(thread_rng()),
}
}
enum EitherRng<L, R> {
Left(L),
Right(R),
}
impl<L, R> RngCore for EitherRng<L, R>
where
L: RngCore,
R: RngCore,
{
fn next_u32(&mut self) -> u32 {
match self {
EitherRng::Left(l) => l.next_u32(),
EitherRng::Right(r) => r.next_u32(),
}
}
fn next_u64(&mut self) -> u64 {
match self {
EitherRng::Left(l) => l.next_u64(),
EitherRng::Right(r) => r.next_u64(),
}
}
fn fill_bytes(&mut self, b: &mut [u8]) {
match self {
EitherRng::Left(l) => l.fill_bytes(b),
EitherRng::Right(r) => r.fill_bytes(b),
}
}
fn try_fill_bytes(&mut self, b: &mut [u8]) -> Result<(), rand::Error> {
match self {
EitherRng::Left(l) => l.try_fill_bytes(b),
EitherRng::Right(r) => r.try_fill_bytes(b),
}
}
}
在任一箱提供了很多这些类型的基本特征实现的。
- 2 回答
- 0 关注
- 601 浏览
添加回答
举报