rust 如何验证clone()是否在`move`闭包中被调用?

i5desfxk  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(106)

我是rust的新手,我想验证move闭包是否调用clone()
我定义了一个Test类型,并实现了Clone trait:

struct Test {
    b : bool,
}

impl Clone for Test {
    fn clone(&self) -> Self {
        println!("clone called");
        *self
    }
    
}

impl Copy for Test {
    
}

字符串
然后在move闭包中使用它:

let test = Test{b:true};

    println!("Memory address of test: {:?}", std::ptr::addr_of!(test.b));

    let c = move || { println!("Memory address of test: {:?}", std::ptr::addr_of!(test.b)); };
    c();    // <--- does clone() be called here?

    println!("Memory address of test: {:?}", std::ptr::addr_of!(test.b));


我期望在c()中,"clone called"将被打印出来,但它没有。
为什么Clone()没有被调用?
输出如下:

> Memory address of test: 0xdf46ddfa9f 
> Memory address of test: 0xdf46ddfaef
> Memory address of test: 0xdf46ddfa9f


地址被更改,这意味着test被复制或克隆。
在这种情况下,如何验证何时调用clone()

lkaoscv7

lkaoscv71#

一个move闭包 * 永远不会 * 调用clone()。任何克隆都必须显式地进行。
你所看到的是test被移动到闭包中,这对于你的最后一个println!来说通常是一个问题,但是因为你的类型实现了Copy,所以一个 copy 被移动到闭包中。每当一个Copy类型被移动时,它实际上是被复制了。
因为Copy是不可用户定义的,并且是隐式使用的,所以在Clone实现中添加逻辑通常不是一个好主意。定义Copy类型的惯用方法是使用派生宏:#[derive(Copy, Clone)] struct Test { ...

相关问题