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)");
}
()

image.png

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





()

image.png

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

───╯

image.png

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

image.png

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;

image.png

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();

image.png

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;`

───╯

image.png