Почему черта impl не может использоваться для возврата нескольких / условных типов?

Я пытаюсь получить генератор случайных чисел. Поскольку я OsRng::new()могу потерпеть неудачу, я хотел бы вернуться, thread_rng()если мне нужно:

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()
    }
}

Однако я получаю сообщение об ошибке, которое я не могу понять:

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(), я не получу выше сообщения об ошибке.

Я не верю, что это дубликат. Как вернуть экземпляр признака из метода? , поскольку в другом вопросе возникает вопрос о том, как можно вернуть черту из функции, и этот вопрос связан с тем, почему компилятор не позволит мне вернуть признак, но хочет, чтобы я возвращал значение, OsRngне являющееся возвращаемым типом функции.

rust,traits,return-type,

0

Ответов: 1


3 принят

impl Traitне эквивалентно возврату объекта интерфейса или базового класса. Это способ сказать: «Я не хочу писать имя конкретного типа, который я возвращаю». Вы по-прежнему возвращаете значение одного определенного типа; вы просто не говорите, какой тип.

Каждая из этих ветвей возвращает разные типы, поэтому проблема. Одного и того же признака недостаточно.

То, что вы, скорее всего, захотите в этом конкретном случае, - это такой объект-объект Box<dyn RngCore>.

fn rng() -> Box<dyn RngCore>
{
    match OsRng::new() {
        Ok(rng) => Box::new(rng),
        Err(_) => Box::new(thread_rng()),
    }
}

Примечание . Если вы используете несколько более старую версию Rust, вам может потребоваться удалить dynключевое слово. Это необязательно в текущем (2015) издании Rust.

ржавчина, черты, возвращение типа,
Похожие вопросы
Яндекс.Метрика