如何验证Rust中move闭包是否调用了clone()方法?
为什么move闭包中没有调用
Clone::clone()? 你遇到的核心问题是**Copy trait的优先级高于Clone**:
因为你的Test结构体同时实现了Copy和Clone trait,当move闭包捕获test时,Rust会使用Copy语义执行按位复制——这是一种底层的内存拷贝操作,完全不需要调用Clone::clone()方法,所以你看不到"clone called"的打印。
内存地址变化的原因是闭包确实获得了一个test的新实例,但这个实例是通过Copy复制出来的,而非Clone克隆的。
如何验证clone()方法的调用?
要触发Clone::clone()的调用,你需要让Rust无法使用Copy语义,具体可以这么做:
移除
Copytrait的实现
修改你的结构体实现:struct Test { b: bool, } impl Clone for Test { fn clone(&self) -> Self { println!("clone called"); *self } } // 移除这一行:impl Copy for Test {}显式调用
clone()来保留原实例的使用权
此时如果直接使用move闭包,原test的所有权会被转移到闭包中,后续无法再访问原test。如果需要同时保留原实例和让闭包使用克隆后的实例,需要显式调用clone():let test = Test{b:true}; println!("Memory address of test: {:?}", std::ptr::addr_of!(test.b)); // 显式克隆,此时会打印"clone called" let test_clone = test.clone(); let c = move || { println!("Memory address of test clone: {:?}", std::ptr::addr_of!(test_clone.b)); }; c(); // 原test仍可正常访问 println!("Memory address of test: {:?}", std::ptr::addr_of!(test.b));
运行这段代码,你就能看到"clone called"的打印,同时闭包中的实例地址和原实例地址不同,符合预期。
内容的提问来源于stack exchange,提问作者Felix F Xu
相关产品推荐
相关产品推荐

