如何修复“无法在此范围内找到派生宏”错误?

46

我有这个:

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

还有一个错误:

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

我为什么会出现这个问题?我该如何解决?

1个回答

48

编译器有一组内置的派生宏,这里有更多信息。对于其他任何宏,您必须导入自定义的derive,然后才能使用。

在 Rust 1.30 之前,您需要在提供宏的创建上使用 #[macro_use]。从 Rust 1.30 开始,您可以改用 use

在此示例中,您需要从 num_derive 创建中导入 FromPrimitive

Rust 1.30 及以后版本

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

在Rust 1.30之前

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

use num_traits::FromPrimitive;

用法

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

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

每个项目都有自己的箱子,其中包含它们自己的派生宏。以下是一个小样例:

  • Num(例如 FromPrimitive)=> num_derive
  • Serde(例如 SerializeDeserialize)=> serde_derive
  • Diesel(例如 InsertableQueryable)=> diesel(实际上与常规箱子相同!)

有些箱子会重新导出其派生宏。例如,您可以使用 Serde 的 derive 特性,然后直接从 serde 箱中导入:

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

FromPrimitive 在 Rust 1.0 之前实际上就是标准库的一部分。它的实用性不足以继续存在于标准库中,因此被移至外部的 num crate 中。一些非常旧的参考资料可能没有更新到这个变化。

有关将类似 C 的枚举类型转换为整数,以及从整数转换回来的更多信息,请参见:


1
我正在使用 Diesel,为什么它没有包含“derive”? - jerry
@jerry,你的问题对我来说毫无意义。derive是编译器理解的特殊语法,没有任何一个crate“包含”它。Crate定义了自己独特的派生宏 - Shepmaster
7
谢谢提到 features = ["derive"]。这节省了我的时间。 - IC_

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接