summaryrefslogtreecommitdiff
path: root/rust/random.rs
blob: 42a8f9476e0d9a4f176c1dca22254f04f14ea85c (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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
fn print_char(c: char) {
    println!("Char: {}", c);
}

// Unit type playground function
// Implicitly returns a unit type
fn implicitly_ret_unit() -> () {
    println!("Returning a ()");
}

fn main() {
    println!("Hello World");

// Char bool unit
//
// char type in rust is 4 bytes, so it can hold unicode
    let c1: char = 'a';
    println!("Size: {}", size_of_val(&c1));

    print_char(c1);

    let _f: bool = false;

    if !_f {
        print_char('F');
    }


// UNIT ype
//
// Unit does not hold any value, returned implicitly
// usually when a function returns nothing

    let _v: () = (); // A unit type is represented as an empty tuple
    //let v: (i32, i32) = (2, 3);

    assert_eq!(_v, implicitly_ret_unit());

    // Unit type size is 0
    println!("Size of a unit type: {}", size_of_val(&_v));

// Statement vs Expression
//
// Statement: instruction perform some action but no value is produced
//
// Expression: Evaluate to a resultant value

    let x: u32 = 5_u32;

    // Initializing y with the value of a whole expression.
    // This is considered an expression because it results in a
    // value.

    // The variable assignment though is a statement
    let y: u32 = {
            let x_squared = x * x;
            let x_cube = x_squared * x;

            // This is the most confusing part....
            // By ommitting the ; here, the result evaluation will be
            // assigned to y.
            x_cube + x_squared + x
    };

    println!("Expression Y: {}", y);

    // Variable is assigned to a unit type:
    // Because the expression ends in a semicolon, there is no
    // value produced by it, to the resulting 'value' is the unit
    // type
    let _z = {
        2 * x;
    };

    println!("What is Z? - {:?}", _z);

    let x = 1;
    let y = {
        let mut x = 1;
        // x += 2 // Variable assignments are statements
        x += 2;   // and produces a unit (nothing) value
        x         // A single variable expression will
                  // produce the variable value
    };

    println!("Type of y: {:?}", y);
    match_me(2, false);
}

// Functions must always annotate types for arguments
fn sum(x: i32, y: i32) -> i32 {
//  x + y; // Would return a unit type
    x + y  // Returns an i32
}

// Diverging functions: Never return to the caller
//  Panics, infinite loops, exiting, etc

fn never_return() -> ! { // ! return type means this is a diverging function
//    unimplemented!(); // interesting macros
    return todo!();
}

fn match_me(tp: u8, b: bool) -> Option<i32> {
    match tp {
        1 => {println!("TP is 1");}
        2 => {println!("TP is 2");}
        _ => {println!("TP is garbage");}
    };

    let _v = match b {
        true => 1,
        false => {
            println!("success");
            panic!("Panic Me");
        }
    };
    return never_return();
}