web-dev-qa-db-fra.com

Comment puis-je corriger «impossible de trouver une macro dérivée dans cette étendue»?

J'ai ceci:

#[derive(FromPrimitive)]
pub enum MyEnum {
    Var1 = 1,
    Var2
}

Et une erreur:

error: cannot find derive macro `FromPrimitive` in this scope                                                                                                 
   |                                                                                                                                                          
38 | #[derive(FromPrimitive)]                                                                                                                                 
   |          ^^^^^^^^^^^^^   

Pourquoi est-ce que je reçois ça? Comment je le répare?

14
jerry

Le compilateur a un petit ensemble de macros dérivées intégrées . Pour les autres, vous devez importer les derives personnalisés avant de pouvoir les utiliser.

Avant Rust 1,30, vous devez utiliser #[macro_use] sur le extern crate ligne de la caisse fournissant les macros. Avec Rust 1,30 et plus, vous pouvez use à la place.

Dans ce cas, vous devez importer FromPrimitive à partir de num_derive Caisse:

Avant Rust 1,30

#[macro_use]
extern crate num_derive; // 0.2.4
extern crate num_traits; // 0.2.6

use num_traits::FromPrimitive;

Après Rust 1,30

use num_derive::FromPrimitive; // 0.2.4 (the derive)
use num_traits::FromPrimitive; // 0.2.6 (the trait)

Utilisation

#[derive(Debug, FromPrimitive)]
pub enum MyEnum {
    Var1 = 1,
    Var2,
}

fn main() {
    println!("{:?}", MyEnum::from_u8(2));
}

Chaque projet a sa propre caisse contenant ses propres macros de dérivation. Un petit échantillon:

  • Num (par exemple FromPrimitive) => num_derive
  • Serde (par exemple Serialize, Deserialize) => serde_derive
  • Diesel (par exemple Insertable, Queryable) => diesel (c'est en fait la même chose que la caisse ordinaire!)

Certaines caisses réexportent leurs macros dérivées. Par exemple, vous pouvez utiliser la fonction derive de Serde puis l'importer directement depuis la caisse serde:

[dependencies]
serde = { version = "1.0", features = ["derive"] }
use serde::{Serialize, Deserialize}; // imports both the trait and the derive macro

FromPrimitive faisait en fait partie de la bibliothèque standard avant Rust 1.0. Ce n'était pas assez utile pour continuer d'exister dans la bibliothèque standard, donc il a été déplacé vers la caisse numérique externe. Certaines références très anciennes n'ont peut-être pas été mises à jour pour cette modification.

Pour plus d'informations sur la conversion d'énumérations de type C vers et à partir d'entiers, voir:

20
Shepmaster