43 个版本 (1 个稳定版)
1.0.0 | 2024 年 8 月 7 日 |
---|---|
1.0.0-beta.6 | 2023 年 10 月 19 日 |
1.0.0-beta.2 | 2023 年 7 月 24 日 |
0.99.18 | 2024 年 6 月 15 日 |
0.1.0 | 2016 年 3 月 28 日 |
#8 在 Rust 模式
3,738,878 每月下载量
用于 7,592 个crate (1,701 直接)
97KB
1.5K SLoC
derive_more
Rust 有许多内建特性,这些特性为其基本类型提供实现,例如 Add
、Not
、From
或 Display
。然而,当您将这些类型封装在自己的结构体或枚举中时,您会丢失这些特性的实现,并需要重新创建它们。当您的结构体非常简单时,例如使用常见的新类型模式(例如 MyInt(i32)
)时,这尤其令人烦恼。
这个库试图消除这些烦恼和相应的样板代码。它是通过允许您为结构体和枚举推导出许多常用特性来实现的。
示例代码
使用这个库,以下代码就可以正常工作
use derive_more::{Add, Display, From, Into};
#[derive(PartialEq, From, Add)]
struct MyInt(i32);
#[derive(PartialEq, From, Into)]
struct Point2D {
x: i32,
y: i32,
}
#[derive(PartialEq, From, Add, Display)]
enum MyEnum {
#[display("int: {_0}")]
Int(i32),
Uint(u32),
#[display("nothing")]
Nothing,
}
assert!(MyInt(11) == MyInt(5) + 6.into());
assert!((5, 6) == Point2D { x: 5, y: 6 }.into());
assert!(MyEnum::Int(15) == (MyEnum::Int(8) + 7.into()).unwrap());
assert!(MyEnum::Int(15).to_string() == "int: 15");
assert!(MyEnum::Uint(42).to_string() == "42");
assert!(MyEnum::Nothing.to_string() == "nothing");
可推导的特性
以下是您可以使用此库推导的所有特性。一些特性推导非常相似,因此后续文档只会显示其中一个。您可以通过名称中的“-like”后缀来识别这些特性。后续文档中使用的将是名称前面的特性。
了解使用此存储库中的某个推导时生成的代码非常重要。因此,下面的链接解释了为每个组中的每个特性生成的代码。
您可以使用 cargo-expand
工具查看为您的特定类型生成的确切代码。这将显示您的代码,其中包含所有宏和推导。
注意:您仍然需要单独推导每个特性。因此,#[derive(Mul)]
并不会自动推导出 Div
。要同时推导两者,您应该使用 #[derive(Mul, Div)]
转换特性
这些特性用于在类型之间自动转换。
格式化特性
这些特性用于以不同方式将结构体转换为字符串。
Debug
Display
-like,包含Display
、Binary
、Octal
、LowerHex
、UpperHex
、LowerExp
、UpperExp
、Pointer
错误处理特性
这些特性用于定义错误类型。
运算符
这些特性可用于运算符重载。
Index
Deref
Not
-like,包含Not
和Neg
Add
-like,包含Add
、Sub
、BitAnd
、BitOr
、BitXor
Mul
-like,包含Mul
、Div
、Rem
、Shr
和Shl
Sum
-like,包含Sum
和Product
IndexMut
DerefMut
AddAssign
-like,包含AddAssign
、SubAssign
、BitAndAssign
、BitOrAssign
和BitXorAssign
MulAssign
-like,包含MulAssign
、DivAssign
、RemAssign
、ShrAssign
和ShlAssign
静态方法
这些不会推导特性,而是推导静态方法。
Constructor
,这会推导出一个可以用来作为构造函数的new
方法。如果您需要对构造函数进行更多自定义,请查看derive-new
包。IsVariant
,对于枚举类型的每个变体foo
,派生一个is_foo
方法。Unwrap
,对于枚举类型的每个变体foo
,派生一个unwrap_foo
方法。TryUnwrap
,对于枚举类型的每个变体foo
,派生一个try_unwrap_foo
方法。
重新导出
此crate还重新导出它添加派生功能的所有标准库特性。因此,当您添加以下代码时,将同时存在 Display
派生和 Display
特性
use derive_more::Display; // also imports `core::fmt::Display`
仅适用于派生宏,不包含相应的特性,应从 derive
模块导入它们
use derive_more::derive::Display; // imports macro only
卫生
为了卫生目的,宏在其展开中使用了 derive_more::*
绝对路径。如果您想在您的crate中重新导出 derive_more
宏而不将其作为直接依赖项使用,这可能会引起麻烦
use my_lib::Display; // re-exported in `my_lib` crate
#[derive(Display)] // error: could not find `derive_more` in the list of imported crates
struct MyInt(i32);
在这种情况下,您应该重新导出 derive_more
模块
use my_lib::{derive_more, Display}; // re-exported in `my_lib` crate
#[derive(Display)] // works fine now!
struct MyInt(i32);
安装
为了避免冗余的编译时间,默认情况下不支持派生。您必须将派生类型作为 Cargo.toml
中的功能启用
[dependencies]
# You can specify the types of derives that you need for less time spent
# compiling. For the full list of features see this crate its `Cargo.toml`.
derive_more = { version = "1", features = ["from", "add", "iterator"] }
[dependencies]
# If you don't care much about compilation times and simply want to have
# support for all the possible derives, you can use the "full" feature.
derive_more = { version = "1", features = ["full"] }
[dependencies]
# If you run in a `no_std` environment you should disable the default features,
# because the only default feature is the "std" feature.
# NOTE: You can combine this with "full" feature to get support for all the
# possible derives in a `no_std` environment.
derive_more = { version = "1", default-features = false }
并将此置于您的Rust文件顶部
// use the derives that you want in the file
use derive_more::{Add, Display, From};
如果您仍在使用Rust 2015,则添加以下内容
extern crate core;
#[macro_use]
extern crate derive_more;
# fn main() {} // omit wrapping statements above into `main()` in tests
MSRV 政策
此库需要Rust 1.75或更高版本。
依赖项
~250–800KB
~18K SLoC