1 个稳定版本
1.0.2 | 2024 年 2 月 7 日 |
---|
203 在 缓存
15KB
213 代码行
cached_field
Rust proc macro 用于在结构体字段上缓存关联函数的结果。类似于 Python 的 @cached_property 类装饰器。
安装
cargo install cached_field
用法
属性宏装饰在结构体的函数实现上;
函数必须将其第一个参数作为 &self 接收;结构体必须有一个相应的可选字段来存储计算结果;
参数
field:必须是字符串字面量,用于指示要缓存结果的结构体字段,默认为它装饰的函数的标识符;
borrow:布尔值,指示转换后的函数返回存储值的引用或副本;如果为 false,返回类型应实现 Copy 特性;默认为 true;
它接受按顺序排列的 (field, borrow) 位置参数或命名值参数;
示例
use cached_field::cached_field;
struct SomeStruct{
some_value: Option<u8>
}
impl SomeStruct{
#[cached_field]
fn some_value(&self) -> u8 {
100
}
#[cached_field("some_value")]
fn same_value(&self) -> u8 {
101
}
}
// s has to be mut
// since some_value requires a mutable reference to SomeStruct to mutate the some_value field inside;
let mut s = SomeStruct{some_value:None};
assert_eq!(100, s.some_value());
assert_eq!(100, s.same_value());
trait 实现
- trait 块中的函数定义应该是转换的最终形式。即接收参数为 &mut self,如果 borrow 为 true,则返回类型为 &T;
- impl 函数签名应采用不可变形式;即 &self 和 T,如果没有 &(如果 trait 签名中 &T 作为返回类型),则不带 &;
- 一般思路是 impl 函数仅用于计算目的,因此它不应修改结构体,并应返回原始结果;
use cached_field::cached_field;
struct AnotherStruct{
another_value: Option<Vec<String>>
}
trait Another {
fn another(&mut self)->&Vec<String>;
}
impl Another for AnotherStruct {
#[cached_field(field = "another_value", borrow = true)]
fn another(&self)->Vec<String>{
vec![1.to_string(),3.to_string(),5.to_string()]
}
}
assert_eq!(vec![1.to_string(),3.to_string(),5.to_string()], *AnotherStruct{another_value:None}.another());
特性
默认情况下,如果 borrow 为 true,宏将检查计算函数的返回类型,如果它找到一个 &,则将 panic;
使用以下特性修改 borrow 为 true 且现有 & 引用被发现时的行为
carry:在转换时保留返回类型不变;
prepend:将 & 预先附加到原始类型,例如将 &T 转换为 &&T;
这些特性是**互斥的**;
依赖项
~255–700KB
~17K SLoC