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