1 个不稳定版本
0.1.0 | 2022年5月9日 |
---|
#1805 在 Rust 模式
913 每月下载量
用于 13 个 包(8 个直接使用)
9KB
clone-macro
一个简单的宏,用于在传递到 move
闭包或块之前克隆数据。
此宏的设计目的是与 rustfmt
格式化兼容。
您可以在整个包中使用此宏,无需每次都显式导入,如下所示
#[macro_use]
extern crate clone_macro;
/* ... */
clone!(/* ... */);
否则,您可以将它作为常规使用 use
。
use clone_macro::clone;
/* ... */
clone!(/* ... */);
语法
clone!
宏接受逗号分隔的列表,可以是以下两种形式之一,可以有一个可选的 mut
前缀修饰符,后跟任意表达式。
例如,以下是一个有效的调用
let a = 1;
let b = 2;
clone!([mut a, b], ());
并简化为以下内容
let a = 1;
let b = 2;
{
let mut a = a.clone();
let b = b.clone();
()
};
克隆列表还可以采用第二种形式,即任意表达式后跟 as
和变量名。例如
let s = "Hello, there!";
clone!([{ s.len() } as len], move || {
assert_eq!(len, "Hello, there!".len());
});
上述内容简化为以下内容
let s = "Hello, there!";
{
let len = "Hello, there!".len();
move || {
assert_eq!(len, "Hello, there!".len());
}
};
此宏在第二个参数是闭包时最有用,这也是它旨在与之一起工作的,尽管并非严格如此。
上述所有形式都可以混合使用,包括为第二种形式添加 mut
修饰符,如下所示
mut { $expr } as $ident
示例
基本用法
use clone_macro::clone;
let s = "You are a beautiful being!".to_string();
let c = clone!([s], move || {
println!("{s}");
});
c();
// `s` wasn't directly moved, rather, cloned first, then moved; therefore,
// we can still use `s`
assert_eq!(s.as_str(), "You are a beautiful being!");
我们还可以将克隆的 move
声明为 mut
use clone_macro::clone;
let a = 7;
let b = 0;
let d = 12;
le
t mut c = clone!([a, mut b, d], move || {
b = 42 - a - d;
println!("a + b + d = {}", a + b + d);
});
c();
assert_eq!(a, 7);
assert_eq!(b, 0);
assert_eq!(d, 12);
高级用法
我们可以克隆任意表达式
use clone_macro::clone;
struct MyStruct {
some_field: String,
}
let s = MyStruct {
some_field: "Beyond measure.".to_string(),
};
let mut c = clone!([{ s.some_field } as some_field, mut { s.some_field } as mut_some_field], move || {
mut_some_field.clear();
assert!(mut_some_field.is_empty());
assert_eq!(some_field.as_str(), "Beyond measure.");
});
c();
assert_eq!(s.some_field.as_str(), "Beyond measure.");
许可证:MIT