summaryrefslogtreecommitdiff
path: root/rust/borrowing.rs
blob: 89a10e962b8223eee5a102dad12a0746357eaf45 (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
// Borrowing data
//
// We can access data created in another scope by borrowing it.
//
// Can be borrowed mutable or immutable.
//
// Borrowing Rules:
//
// - At any given time, you can have either a
//      SINGLE MUTABLE reference or
//      MANY IMMUTABLE references
// - References must always be valid
//

// We can define references by
//
// Passing the reference to a var:  let x = &var
// Using the ref keyworkd like:     let ref x = var

fn main() {
    let s1 = String::from("hello");

    // Pass a reference to String s1
    // this is a reference to the s1 not the string per se
    let len: usize = calculate_length(& s1);

    // Mutable ref
    let mut c = String::from("Howdy");

    // Pass a mutable reference to change function
    change(&mut c);

    // We can still use s1 here, because s1 is still the owner.
    println!("The length of '{}' is {}.", s1, len);
    println!("{}", c);

    print_pointer();
}


// The function receives a 'reference' to a String
fn calculate_length(s: & String) -> usize {
    return s.len();
}

fn change(c: &mut String) {
    c.push_str(" partner");
}

fn print_pointer() {
    let x: i32 = 5;

    let p: &i32 = &x;

    println!("PTR is: {:p}", p);
}
// This function is just an example of 2nd rule violation
// It returns a reference to a string that will run out of
// scope once the function returns.
// Thanks to that, we return a dangling pointer. Rustc won't
// let us compile it.

// Could be fixed by returning the String data itself
//fn dangling_ptr() -> &String {
//    let s = String::from("howdy");
//
//    return &s;
//}