#clone #utility-macro #macro #utility

clone-macro

在将数据移动到移动闭包/块之前进行克隆的超简单实用宏。

1 个不稳定版本

0.1.0 2022年5月9日

#1805Rust 模式

Download history 236/week @ 2024-03-13 347/week @ 2024-03-20 330/week @ 2024-03-27 214/week @ 2024-04-03 140/week @ 2024-04-10 178/week @ 2024-04-17 211/week @ 2024-04-24 392/week @ 2024-05-01 169/week @ 2024-05-08 151/week @ 2024-05-15 141/week @ 2024-05-22 131/week @ 2024-05-29 108/week @ 2024-06-05 116/week @ 2024-06-12 275/week @ 2024-06-19 386/week @ 2024-06-26

913 每月下载量
用于 13 包(8 个直接使用)

MIT 许可证

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

无运行时依赖