在rust中有个常用个方法clone
,按字面意思就是克隆。这个函数的作用是对对象进行深度拷贝,生成的新对象与原对象相互独立。
很多常用的类型或者容器类型都支持clone
,例如rust中的HashMap
也支持clone
,我们用一段代码实验一下。
#[test]
fn test_hash_map_clone() {
let xx: Arc<Mutex<HashMap<String, String>>> = Arc::new(Mutex::new(HashMap::new()));
let mut mp = xx.lock().unwrap();
mp.insert("hi".to_string(), "hello".to_string());
println!("origin: {:?}", mp);
let mut cp = mp.clone();
cp.insert("k".to_string(), "v".to_string());
println!("origin: {:?}", mp);
println!("cp : {:?}", cp);
}
输出
running 1 test
origin: {"hi": "hello"}
origin: {"hi": "hello"}
cp : {"hi": "hello", "k": "v"}
test test_hash_map_clone ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.00s
上面的测试代码运行结果表示,修改克隆后的对象cp
,源对象mp不会发生变化。
那么我们自己定义的类型如何才能支持clone
呢?使用#[derive(Clone)]
这个指令修饰自定义类型,就会自动支持clone
,但是要注意,如果自定义类型结构体里,如果有字段类型不支持clone
,将无法通过#[derive(Clone)]
指令快速支持clone
。
自定义类型clone
测试如下
#[derive(Debug, Clone)]
struct User {
name: String,
age: i32,
}
#[test]
fn test_struct_clone() {
let mut u1 = User {
name: "rex".to_string(),
age: 1,
};
println!("origin: {:?}", u1);
let mut ucp = u1.clone();
ucp.name = "agnes".to_string();
ucp.age = 2;
println!("origin: {:?}", u1);
println!("cp : {:?}", ucp);
u1.age = 3;
println!("origin: {:?}", u1);
println!("cp : {:?}", ucp);
}
运行结果
running 1 test
origin: User { name: "rex", age: 1 }
origin: User { name: "rex", age: 1 }
cp : User { name: "agnes", age: 2 }
origin: User { name: "rex", age: 3 }
cp : User { name: "agnes", age: 2 }
test test_struct_clone ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.00s
同样可以看到,修改clone
后的对象,源对象不变,修改源对象,clone
后的对象也不变。