Rust: fn foo () -> Result <()> выдает «ожидаемые аргументы 2 типа» - PullRequest
0 голосов
/ 03 декабря 2018

Почему Result<()> не допускается при компиляции этого бита кода Rust?Это разительное изменение между выпусками Rust?

fn run() -> Result<()> {
    let (tx, rx) = channel();

    thread::spawn(move || {
        do_things_with_tx(&exit_tx);
    });

    match exit_rx.recv() {
        Ok(result) => if let Err(reason) = result {
            return Err(reason);
        },
        Err(e) => {
            return Err(e.into());
        },
    }

    Ok(())
}

Компилятор говорит:

error[E0107]: wrong number of type arguments: expected 2, found 1
    --> src/main.rs:1000:18
     |
1000 | fn run_wifi() -> Result<()> {
     |                  ^^^^^^^^^^ expected 2 type arguments

Когда я настраиваю тип возврата на Result<(), Err>, он говорит:

error[E0107]: wrong number of type arguments: expected 2, found 0
    --> src/main.rs:1000:29
     |
1000 | fn run() -> Result<(), Err> {
     |                        ^^^ expected 2 type arguments

Это из проекта wifi-connect .Утром свяжемся с воспроизводимым MVCE.

Ответы [ 2 ]

0 голосов
/ 29 апреля 2019

С Язык программирования Rust раздел The?Оператор может использоваться только в функциях, которые возвращают результат

use std::error::Error;
use std::fs::File;

fn main() -> Result<(), Box<dyn Error>> {
    let f = File::open("hello.txt")?;

    Ok(())
}
0 голосов
/ 03 декабря 2018

Определение Result является и всегда было следующим:

pub enum Result<T, E> {
    Ok(T),
    Err(E),
}

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

С другой стороны, можно найти много библиотек и соответствующих документов, показывающих Result с одним аргументом типа, как в Result<()>.Что дает?

Это все еще не волшебство.По соглашению библиотеки создают псевдонимы типов для типов результатов на уровне ящика или модуля.Это работает довольно хорошо, потому что те, кто обычно выдает ошибки одного и того же локально созданного типа.

pub type Result<T> = Result<T, Error>;

На самом деле, это настолько распространено, что ящик error-chain,один из множества вспомогательных ящиков типа ошибки автоматически создает это определение при использовании макроса error_chain!.Таким образом, если вы находитесь в проекте, использующем error-chain (, например, wifi-connect), или используете библиотеку, которая может использовать или не использовать error-chain, вы должны предположить, что упоминание Result<T> - псевдонимы локального типа для доменного Result<T, Error>.В случае сомнений, щелкнув по этому типу на сгенерированных страницах документации, вы перейдете к конкретному определению (в данном случае к псевдониму).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...