let a = String::from("hello"); let b = a; println!("a = {}, b = {}", a, b);
// got error: // error[E0382]: borrow of moved value: `a` // 3 | let a = String::from("hello"); // | - move occurs because `a` has type `String`, which does not implement the `Copy` trait // 4 | let b = a; // | - value moved here // 5 | println!("a = {}, b = {}", a, b); // | ^ value borrowed here after move
深拷贝(clone)
如果clone的话可以复制一份,但是这样的话就需要开辟一块新的内存,不是很高效。
1 2 3 4 5
let a = String::from("hello"); // let b = a; let b = a.clone(); println!("a = {}, b = {}", a, b); // output: a = hello, b = hello
引用计数 (reference count)
想要实现多个所有者,又开销小,可以用引用计数,对应的类型是Rc。
Rc只会在复制时增加引用计数,当引用计数为0时,会自动调用drop方法,释放内存。
1 2 3 4 5 6 7 8
let a = Rc::new(String::from("hello")); let _b = Rc::clone(&a); { let _b = Rc::clone(&a); println!("reference count {}", Rc::strong_count(&a)); // 3, will be 2 after this block out of scope } println!("reference count {}", Rc::strong_count(&a)); // 2
letmut a = Rc::new(String::from("hello")); let b = Rc::clone(&a); // allocate a new string (copy on write) (*Rc::make_mut(&mut a)).push_str( " world"); println!("{} {}", a, b); // hello world hello
let c = Rc::clone(&a); println!("{} {} {}", a, b, c); // hello world hello hello world
for _ in0..3 { let val = Arc::clone(&val); thread::spawn(move || { let v = *val.as_ref() + 1; println!("{v:?}"); }); } thread::sleep(std::time::Duration::from_secs(1)); }