8个版本
0.1.8 | 2022年6月27日 |
---|---|
0.1.7 | 2022年6月27日 |
#1046 在 数据结构
每月30次下载
在 corresponding-macros 中使用
10KB
对应
这个Rust包可以用于在模块内复制结构体。只有同名同型的字段会被复制,因此包名为对应。
通过在模块上添加属性 derive_corresponding
,将 MoveCorresponding
特性实现为模块内所有的结构体。这使得可以在具有属性模块的所有结构体上调用 move_corresponding
函数,并将模块内的所有结构体作为参数。对于模块中所有派生自 Default
的结构体,将实现 From
特性。
示例
在一个模块上添加 derive_corresponding
属性。这个模块必须声明为内联。
use corresponding::derive_corresponding;
#[derive_corresponding]
mod my_mod {
#[derive(Debug, Default)]
pub struct A {
pub a: u8,
pub b: u8,
pub c: u8,
}
#[derive(Debug, Clone)]
pub struct B {
pub a: u8,
pub b: Option<u8>,
pub d: u8,
}
}
确保 MoveCorresponding
在作用域内,并开始从 B
移动对应的字段到 A
,反之亦然
use corresponding::MoveCorresponding;
use my_mod::*;
fn start_moving() {
let mut a = A { a: 1, b: 1, c: 1 };
let mut b = B { a: 2, b: Some(2), d: 2 };
a.move_corresponding(b.clone());
println!("{a:?}"); // Output: A { a: 2, b: 2, c: 1 }
let a2 = A { a: 3, b: 3, c: 3 };
b.move_corresponding(a2);
println!("{b:?}"); // Output: B { a: 3, b: Some(3), d: 2 }
}
因为结构体 A
派生自 Default
,它也会实现 From
。所以你可以将 B
转换为 A
fn start_transforming() {
let b = B { a: 4, b: Some(4), d: 4 };
let a: A = b.into();
println!("{a:?}"); // Output: A { a: 4, b: 4, c: 0 }
}
结构体 B
没有派生自 Default
,因此你不能将 A
转换为 B
。在这种情况下没有实现 From
。
还可以在 examples
文件夹中看到一个工作示例。
选项
同时,类型为 T
和 Option<T>
的字段也被认为是对应的。
- 将
Option<T>
移动到T
时,只有当源字段是Some(值)
时,才会设置目标字段 - 将
T
移动到Option<T>
将始终将目标字段设置为Some(value)
- 将
Option<T>
移动到Option<T>
只在源字段为Some(value)
时设置目标字段
这意味着无法使用 move_corresponding
将 Option
设置为 None
不支持更深层次的 Option
,因此 Option<Option<V>>
被视为 Option<T>
,其中 T
= Option<V>
展开
如果您已安装 cargo-expand
,您可以通过运行来查看生成的实现
$ cd corresponding
$ cargo expand --example corresponding
依赖关系
~1.5MB
~36K SLoC