Ownership
{
let point = Box::new((0.625, 0.5)); // point allocated here
let label = format!("{:?}", point); // label allocated here
assert_eq!(label, "(0.625, 0.5)");
}
()
struct Person { name: String, birth: i32 }
let mut composers = Vec::new();
composers.push(Person {
name: "Abc".to_string(),
birth: 123,
});
composers.push(Person {
name: "DEF".to_string(),
birth: 444,
});
composers.push(Person {
name: "ASD".to_string(),
birth: 555,
});
for composer in &composers {
println!("{}, born {}", composer.name, composer.birth);
}
Abc, born 123
DEF, born 444
ASD, born 555
()
Moves
let s = vec!["udon".to_string(), "ramen".to_string(), "soba".to_string()];
let t = s;
let u = s;
[E0382] Error: use of moved value: `s`
╭─[command_4:1:1]
│
1 │ let s = vec!["udon".to_string(), "ramen".to_string(), "soba".to_string()];
│ ┬
│ ╰── move occurs because `s` has type `Vec<String>`, which does not implement the `Copy` trait
2 │ let t = s;
│ ┬│
│ ╰── value moved here
│ │
│ ╰─ help: consider cloning the value if the performance cost is acceptable: `.clone()`
3 │ let u = s;
│ ┬
│ ╰── value used here after move
───╯
let s = vec!["udon".to_string(), "ramen".to_string(), "soba".to_string()];
let t = s.clone();
let u = s.clone();
More Operations That Move
let mut s = "Govinda".to_string();
s = "Siddhartha".to_string(); // value "Govinda" dropped here
let mut s = "Govinda".to_string();
let t = s;
s = "Siddhartha".to_string(); // nothing is dropped here
Moves and Control Flow
Moves and Indexed Content
// Build a vector of the strings "101", "102", ... "105"
let mut v = Vec::new();
for i in 101 .. 106 {
v.push(i.to_string());
}
()
// Pull out random elements from the vector.
let third = v[2]; // error: Cannot move out of index of Vec
let fifth = v[4]; // here too
[E0507] Error: cannot move out of index of `Vec<String>`
╭─[command_9:1:1]
│
2 │ let third = v[2]; // error: Cannot move out of index of Vec
│ ┬─┬─
│ ╰───── help: consider borrowing here: `&`
│ │
│ ╰─── move occurs because value has type `String`, which does not implement the `Copy` trait
───╯
[E0507] Error: cannot move out of index of `Vec<String>`
╭─[command_9:1:1]
│
3 │ let fifth = v[4]; // here too
│ ┬─┬─
│ ╰───── help: consider borrowing here: `&`
│ │
│ ╰─── move occurs because value has type `String`, which does not implement the `Copy` trait
───╯
// 1. Pop a value off the end of the vector:
let fifth = v.pop().expect("vector empty!");
assert_eq!(fifth, "105");
// 2. Move a value out of a given index in the vector,
// and move the last element into its spot:
let second = v.swap_remove(1);
assert_eq!(second, "102");
// 3. Swap in another value for the one we're taking out:
let third = std::mem::replace(&mut v[2], "substitute".to_string());
assert_eq!(third, "103");
// Let's see what's left of our vector.
assert_eq!(v, vec!["101", "104", "substitute"]);
struct Person { name: Option<String>, birth: i32 }
let mut composers = Vec::new();
composers.push(Person { name: Some("Palestrina".to_string()),
birth: 1525 });
let first_name = composers[0].name;
[E0507] Error: cannot move out of index of `Vec<Person>`
╭─[command_13:1:1]
│
1 │ let first_name = composers[0].name;
│ ┬───────┬────────
│ ╰────────────────── help: consider borrowing here: `&`
│ │
│ ╰────────── move occurs because value has type `Option<String>`, which does not implement the `Copy` trait
───╯
let first_name = std::mem::replace(&mut composers[0].name, None);
assert_eq!(first_name, Some("Palestrina".to_string()));
assert_eq!(composers[0].name, None);
let first_name = composers[0].name.take();
Copy Types: The Exception to Moves
let string1 = "somnambulance".to_string();
let string2 = string1;
let num1: i32 = 36;
let num2 = num1;
struct Label { number: u32 }
fn print(l: Label) { println!("STAMP: {}", l.number); }
let l = Label { number: 3 };
print(l);
println!("My label number is: {}", l.number);
[E0382] Error: borrow of moved value: `l`
╭─[command_17:1:1]
│
3 │ let l = Label { number: 3 };
│ ┬
│ ╰── move occurs because `l` has type `Label`, which does not implement the `Copy` trait
4 │ print(l);
│ ┬
│ ╰── value moved here
5 │ println!("My label number is: {}", l.number);
│ ────┬───
│ ╰───── value borrowed here after move
───╯
#[derive(Copy, Clone)]
struct Label { number: u32 }
#[derive(Copy, Clone)]
struct StringLabel { name: String }
[E0204] Error: the trait `Copy` cannot be implemented for this type
╭─[command_19:1:1]
│
1 │ #[derive(Copy, Clone)]
│ ──┬─
│ ╰─── error: the trait `Copy` cannot be implemented for this type
2 │ struct StringLabel { name: String }
│ ──────┬─────
│ ╰─────── this field does not implement `Copy`
───╯
Rc and Arc: Shared Ownership
use std::rc::Rc;
// Rust can infer all these types; written out for clarity
let s: Rc<String> = Rc::new("shirataki".to_string());
let t: Rc<String> = s.clone();
let u: Rc<String> = s.clone();
assert!(s.contains("shira"));
assert_eq!(t.find("taki"), Some(5));
println!("{} are quite chewy, almost bouncy, but lack flavor", u);
shirataki are quite chewy, almost bouncy, but lack flavor
s.push_str(" noodles");
[E0596] Error: cannot borrow data in an `Rc` as mutable
╭─[command_22:1:1]
│
1 │ s.push_str(" noodles");
│ ┬
│ ╰── cannot borrow as mutable
│
│ Note: You can change an existing variable to mutable like: `let mut x = x;`
───╯