14个不稳定版本 (5个重大变更)
0.5.0 | 2024年8月7日 |
---|---|
0.4.0 | 2024年5月12日 |
0.3.0 | 2023年5月25日 |
0.2.0 | 2020年8月18日 |
0.0.2 | 2017年4月23日 |
#30 in 过程宏
每月208,669次下载
用于 134 个crate(67 直接)
37KB
573 行
Derive Getters
为命名结构体生成字段获取方法的简单 derive 宏。还包括一个额外的 derive,Dissolve
,它消费结构体并返回所有字段的一个元组,顺序与声明顺序相同。对于目标结构体字段的任何文档注释都将复制到相应的获取器中。如果没有注释,则应生成注释。
当我在创建用于将JSON反序列化的各种数据结构时,产生了对 Getters
宏的需求。这些数据结构有很多字段需要访问,一旦创建后就不会改变。可以在任何地方使用 pub
,但这将允许修改字段,这正是这个 derive 试图避免的。
获取器将根据 约定 生成。这意味着生成的方法将位于结构体命名空间内。
关于 Dissolve
,有时在转换过程中必须消耗结构体。一个简单的方法是返回所有结构体字段的一个元组。因此,可以将 Dissolve
视为一个“获取(移动)所有内容”的方法调用。
本crate不会做什么
没有可变获取器,也没有计划。也没有设置器,将来也不会有。
Rust 文档
安装
添加到您的 Cargo.toml
[dependencies]
derive-getters = "0.5.0"
然后在需要的地方导入 Getters
或 Dissolve
宏(假设 2018 版本)。
use derive_getters::{Getters, Dissolve};
否则,只需在 crate 根目录导入。
#[macro_use]
extern crate derive_getters;
特性
auto_copy_getters
- 启用自动为原始类型生成复制获取器(按值返回而不是按引用返回)。
用法
当您有一个需要自动 derive 获取器的结构体时...只需在顶部添加 derive,如下所示;
#[derive(Getters)]
pub struct MyCheesyStruct {
x: i64,
y: i64,
}
将为 MyCheesyStruct
生成一个新的实现。
/// Auto-generated by `derive_getters::Getters`.
impl MyCheesyStruct {
/// Get field `x` from instance of `MyCheesyStruct`.
pub fn x(&self) -> &i64 {
&self.x
}
/// Get field `y` from instance of `MyCheesyStruct`.
pub fn y(&self) -> &i64 {
&self.y
}
}
您还可以推导出“值获取器”,它们通过值而不是引用返回。
#[derive(Getters)]
pub struct MyCheesyStruct {
#[getter(copy)]
x: i64,
#[getter(copy)]
y: i64,
}
这将为 MyCheesyStruct
生成以下实现。
/// Auto-generated by `derive_getters::Getters`.
impl MyCheesyStruct {
/// Get field `x` from instance of `MyCheesyStruct`.
pub fn x(&self) -> i64 {
self.x
}
/// Get field `y` from instance of `MyCheesyStruct`.
pub fn y(&self) -> i64 {
self.y
}
}
如果您想自动为原始类型生成值获取器,可以启用 auto_copy_getters
功能。
建议启用 auto_copy_getters
,因为它可以使您的代码更快(无需解引用指针)。Rust 参考文档 建议实现 Copy
特性。
此软件包还可以处理具有简单泛型参数和生存期注解的结构体。有关更多信息,请参阅 文档。
#[derive(Getters)]
pub struct StructWithGeneric<'a, T> {
concrete: f64,
generic: T,
text: &'a str,
}
使用 Dissolve
,可以这样使用:
#[derive(Dissolve)]
pub struct Solid {
a: u64,
b: f64,
c: i64,
}
将为 Solid
生成以下实现:
/// Auto-generated by `derive_getters::Dissolve`.
impl Solid {
/// Dissolve `Solid` into a tuple consisting of its fields in order of declaration.
pub fn dissolve(self) -> (u64, f64, i64) {
(self.a, self.b, self.c)
}
}
属性
Getters
属性
- 在字段上使用
#[getter(skip)]
以跳过为其生成获取器。 - 在字段上使用
#[getter(copy)]
以通过复制而不是引用返回值(注意:值必须实现Copy
特性)。 - 在字段上使用
#[getter(rename = "name")]
以将获取器名称更改为 "name"。
Dissolve
属性
- 在结构体上使用
#[dissolve(rename = "name")]
以将解溶函数的名称更改为 "name"。
注释保留
字段上的文档注释应复制到各自的获取器中。如果没有字段的注释,则应生成一个。
例如,这个结构体:
#[derive(Getters, Dissolve)]
#[dissolve(rename = "melt")]
struct Funky<'a, T> {
number: i64,
/// This is commented.
commented: T,
/// This comment is over
/// many lines.
/// Here's another line.
#[getter(rename = "floating")]
many_line: f32,
/**
* This is one of those
* pesky multi-line
* comments.
*/
multi_line: &'a str,
/// We don't care for this field.
#[getter(skip)]
ignore_me: u16,
#[doc = r" A doc comment"]
one_comment: u64,
#[doc = include_str!("../COMMENTS.md")]
incl_comment: u64,
#[doc(hidden)]
/// This comment should be hidden.
hideme: u64,
// This comment won't show up.
bad: u64,
}
将自动生成以下内容:
/// Auto-generated by `derive_getters::Getters`.
impl<'a, T> Funky<'a, T> {
/// Get field `number` from instance of `Funky`.
pub fn number(&self) -> &i64 {
&self.number
}
/// This is commented.
pub fn commented(&self) -> &T {
&self.commented
}
/// This comment is over
/// many lines.
/// Here's another line.
pub fn floating(&self) -> &f32 {
&self.many_line
}
/**
* This is one of those
* pesky multi-line
* comments.
*/
pub fn multi_line(&'a self) -> &'a str {
self.multi_line
}
/// A doc comment
pub fn one_comment(&self) -> &u64 {
&self.one_comment
}
/**Comments sourced from a file included at compile time.
*/
pub fn incl_comment(&self) -> &u64 {
&self.incl_comment
}
#[doc(hidden)]
/// This comment should be hidden.
pub fn hideme(&self) -> &u64 {
&self.hideme
}
/// Get field `bad` from instance of `Funky`.
pub fn bad(&self) -> &u64 {
&self.bad
}
}
/// Auto-generated by `derive_getters::Dissolve`.
impl<'a, T> Funky<'a, T> {
/// Dissolve `Funky` into a tuple consisting of its fields in order of declaration.
pub fn melt(self) -> (i64, T, f32, &'a str, u16, u64, u64, u64, u64) {
(
self.number,
self.commented,
self.many_line,
self.multi_line,
self.ignore_me,
self.one_comment,
self.incl_comment,
self.hideme,
self.bad,
)
}
}
看!现在有了注释!
测试
由于新 #[cfg]
功能 auto_copy_getters
的存在,并非所有测试都将使用常规的 cargo test
运行。要一次性运行所有测试,请尝试使用 cargo-hack 软件包。安装后,运行:
cargo hack test --feature-powerset
注意事项
- 无法为单元结构体、元组结构体或枚举推导
Getters
。 - 无法为单元结构体或枚举推导
Dissolve
。 - 在没有
auto_copy_getters
的情况下,所有获取器方法都返回对其字段的不可变引用,&
。这意味着对于某些类型,可能会变得有些尴尬。但是,在设置auto_copy_getters
功能的情况下,生成的获取器将不会使用任何引用,用于原始的Copy
类型。
备选方案
依赖项
~275–730KB
~17K SLoC