web-dev-qa-db-fra.com

Rust Erreur: La taille des valeurs de type `(dyn std :: error :: Error + 'static)` ne peut pas être connue au moment de la compilation

tout d'abord, je tiens à mentionner qu'il existe de nombreuses questions similaires sur StackOverflow et sur le Web, mais je ne peux tout simplement pas comprendre comment résoudre cette erreur pour mon cas.

J'ai donc une structure, qui représente mon propre type d'erreur:

#[derive(Debug)]
pub struct Error {
    msg: String,
}

Ensuite, j'ai continué à implémenter Display et std::error::Error pour mon type d'erreur:

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.msg)
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        &self.msg
    }
}

Maintenant, j'ai essayé de mettre en œuvre std::convert::From afin que je puisse utiliser mon type d'erreur de manière transparente avec le ? opérateur:

impl From<dyn std::error::Error> for Error {
    fn from(err: dyn std::error::Error) -> Self {
        Error {
            msg: err.to_string(),
        }
    }
}

Mais alors le compilateur Rust me donne cette erreur:

error[E0277]: the size for values of type `(dyn std::error::Error + 'static)` cannot be known
at compilation time
  --> wasm_api/geohub_wasm_filehandler_api/src/lib.rs:33:6
   |
33 | impl From<dyn std::error::Error> for Error {
   |      ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |

Je sais que par défaut, les fonctions génériques ne fonctionneront que sur les types qui ont une taille connue au moment de la compilation. Mais je ne sais pas comment résoudre ce problème correctement.

Merci de votre aide!

Lien vers le code sur Rust-Playground:

https://play.Rust-lang.org/?version=stable&mode=debug&edition=2018&Gist=568900e8c7847c1f79781fa9bb6d499d

6
Samuel Dressel

Comme @SirDarius dit ci-dessus, vous ne pouvez pas faire cela pour un Error car Error n'est pas un type, c'est un trait. (Si vous venez de la POO, pensez à un trait comme une interface. Vous ne pouvez pas convertir une interface en un autre type d'objet car l'interface n'a pas d'état sous-jacent - il n'y a pas de "là".)

La bonne façon de gérer cela est d'implémenter From pour chaque type de béton que vous devez prendre en charge. Cette vidéo m'a vraiment aidé à comprendre comment tout cela s'emboîte.

1
Tim Keating