Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.9k views
in Technique[技术] by (71.8m points)

rust - How do I fix "cannot find derive macro in this scope"?

I have this:

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

And an error:

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

Why do I get this? How do I fix it?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The compiler has a small set of built-in derive macros. For any others, you have to import the custom derives before they can be used.

Before Rust 1.30, you need to use #[macro_use] on the extern crate line of the crate providing the macros. With Rust 1.30 and up, you can use them instead.

In this case, you need to import FromPrimitive from the num_derive crate:

After Rust 1.30

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

Before Rust 1.30

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

use num_traits::FromPrimitive;

Usage

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

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

Each project has their own crate containing their own derive macros. A small sample:

  • Num (e.g. FromPrimitive) => num_derive
  • Serde (e.g. Serialize, Deserialize) => serde_derive
  • Diesel (e.g. Insertable, Queryable) => diesel (it's actually the same as the regular crate!)

Some crates re-export their derive macros. For example, you can use the derive feature of Serde and then import it from the serde crate directly:

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

FromPrimitive was actually part of the standard library before Rust 1.0. It wasn't useful enough to continue existing in the standard library, so it was moved to the external num crate. Some very old references might not have been updated for this change.

For more information about converting C-like enums to and from integers, see:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...