web-dev-qa-db-fra.com

fn foo () -> Résultat <()> renvoie "les arguments de type 2 attendus"

Pourquoi Result<()> n'est-il pas autorisé lors de la compilation de ce bit de code Rust? Est-ce un changement de rupture entre les éditions 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(())
}

Le compilateur dit:

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

Quand je Tweak le type de retour à Result<(), Err>, il dit:

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

Cela vient du projet de connexion wifi .

7
Petrus Theron

La définition de Result est et a toujours été la suivante:

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

Cette définition est même présentée dans le Rust langage de programmation , pour montrer à quel point c'est simple. En tant que type de somme générique d'un [~ # ~] ok [~ # ~] résultat et un résultat d'erreur , il attend toujours deux paramètres de type et le compilateur se plaindra s'il ne peut pas les déduire ou si la liste des arguments de type n'a pas la longueur attendue.

D'un autre côté, on peut trouver de nombreuses bibliothèques et documents respectifs montrant un Result avec un seul argument de type, comme dans Result<()>. Ce qui donne?

Ce n'est toujours pas magique. Par convention, les bibliothèques créent des alias de type pour les types de résultats au niveau d'une caisse ou d'un module. Cela fonctionne assez bien car il est courant que ceux-ci produisent des erreurs du même type créé localement.

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

En fait, il est si courant que la caisse error-chain , l'une des nombreuses caisses d'assistance de type d'erreur, crée automatiquement cette définition lors de l'utilisation de la macro error_chain!. En tant que tel, si vous êtes dans un projet en utilisant error-chain ( comme wifi-connect ), ou en utilisant une bibliothèque qui peut ou non utiliser error-chain , vous devez supposer que les mentions de Result<T> sont des alias de type local vers un Result<T, Error> spécifique au domaine. En cas de doute, cliquer sur ce type dans les pages de documentation générées vous dirigera vers la définition concrète (dans ce cas, l'alias).

16

De Le Rust langage de programmation section L'opérateur? Ne peut être utilisé que dans les fonctions qui renvoient le résultat

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

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

    Ok(())
}
3
E-rich