summaryrefslogtreecommitdiff
path: root/rust/ownership.rs
blob: 3a967434309cc8bf7a9dc20cf7ff64b37c5bc469 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Rules of ownership:
//
// 1 - each value has an owner
// 2 - only one owner allowed
// 3 - if owner goes out of scope, value will be freed
//
// Scopes: Global, local -> Similar to C

fn main() -> () {

    let h = "Hello"; // s is the owner
    let s = get_string();

//  let s2 = s;     // This only copies the pointer value, not the
                    // String data type
                    //
                    // This essentially violates the ownership rule of
                    // a single owner.
                    // Because of that, rust compiler drops the ownership
                    // of the original variable 's', only s2 owns the pointer
                    // now.

    let s2 = s.clone(); // Deep copy String s

    println!("{}", h);

    println!("{}", s2);

    println!("{}", s);  // generates an error due to ownership if .clone ain't used


    // Transferring ownership

    take_ownership(s);  // 's' value is moved to the function. From now on, 's' is
                        // no longer valid here.

//  println!("{}", s); // KABOOM

    // give_ownership allocate and return us a
    // String type, giving s3 ownership of the
    // allocated String.
    // s3 belongs to this scope now.
    let s3 = give_ownership();

    // Sending and getting ownership back

    let s5 = String::from("This is mine");
    let s5 = give_me_back(s5);  // I'm shadowing s5 here, but I could have used
                                // something else

    println!("{} {}", s3, s5);

} // s - only valid to here

fn give_me_back(s: String) -> String {

    return s;
}

fn give_ownership() -> String {

    // The ownership of the String allocated here
    // will be transferred to the caller.
    return String::from("Jumento celestino");
}
fn take_ownership(s: String) {
    println!("Ownership transfer completed. \n{}", s);

    // Reaching end of this scope will free 's'
}

fn get_string() -> String {
    return String::from("Ronaldo");
}