为什么不能使用 impl trait 返回多个/条件类型? [英] Why can impl trait not be used to return multiple / conditional types?
问题描述
我正在尝试获取一个随机数生成器.由于 OsRng::new()
可能会失败,如果必须的话,我想回退到 thread_rng()
:
I'm trying to get a random number generator. Since OsRng::new()
can fail, I'd like to fall back to thread_rng()
if I have to:
extern crate rand; // 0.5.5
use rand::{thread_rng, OsRng, RngCore};
fn rng() -> impl RngCore
{
match OsRng::new() {
Ok(rng) => rng,
Err(e) => thread_rng()
}
}
但是,我收到了我无法理解的错误消息:
However, I get this error message which I cannot understand:
error[E0308]: match arms have incompatible types
--> src/lib.rs:6:5
|
6 | / match OsRng::new() {
7 | | Ok(rng) => rng,
8 | | Err(e) => thread_rng(),
| | ------------ match arm with an incompatible type
9 | | }
| |_____^ expected struct `rand::OsRng`, found struct `rand::ThreadRng`
|
= note: expected type `rand::OsRng`
found type `rand::ThreadRng`
为什么编译器需要 rand::OsRng
而不是 RngCore
的实现?如果我删除 match
并直接返回 thread_rng()
,则不会收到上述错误消息.
Why is the compiler expecting rand::OsRng
here instead of an implementation of RngCore
? If I remove the match
and directly return thread_rng()
, I don't get above error message.
我不认为这是 如何从方法返回特征的实例?,因为另一个问题是关于如何从函数返回一个特征,这个问题是关于为什么编译器不允许我返回一个特征但想要我返回一个OsRng
,它不是函数的返回类型.
I do not believe that this is a duplicate of How do I return an instance of a trait from a method?, as the other question is asking about how one can return a trait from a function, and this question is about why the compiler will not allow me to return a trait but wants me to return an OsRng
which is not the return type of the function.
推荐答案
impl Trait
不等同于返回接口或基类对象.这是一种说我不想写我要返回的特定类型的名称"的方式.您仍然返回单个特定类型的值;你只是没有说哪种类型.
impl Trait
is not equivalent to returning an interface or base class object. It's a way of saying "I don't want to write the name of the specific type I'm returning". You're still returning a value of a single, specific type; you just aren't saying which type.
这些分支中的每一个都返回不同的类型,因此是问题所在.实现相同的特征是不够的.
Each of those branches is returning different types, hence the problem. Implementing the same trait is not enough.
在这种特定情况下,您可能想要的是像 Box<dyn RngCore>
这样的 trait 对象.
What you likely want in this specific case is a trait object like 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 中是可选的.
Note: if you are using a slightly older version of Rust, you may need to remove the dyn
keyword. It's optional in the previous (2015) edition of Rust.
这篇关于为什么不能使用 impl trait 返回多个/条件类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!