You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A boolean type in Rust has two possible values: true and false.
Booleans are one byte in size.
Booleans are specified using bool.
e.g) let f: bool = false;
A character type in Rust is used to represent letters.
Characters are four bytes in size and represents a Unicode Scalar Value.
Characters are specified using char.
Character literals are specified with single quotes, as opposed to string literals, which use double quotes.
e.g) let c: char = 'z';
Compound types can group multiple values into one type.
Rust has two primitive compound types: tuples and arrays.
Tuples have a fixed length.
Once decleared, they cannot grow or shrink in size.
The tuple is specified with a comma-separated list of values inside parentheses.
e.g) let tup: (i32, f64, u8) = (500, 6.4, 1);
Rust supports pattern matching to destructure a tuple value.
e.g) let (x, y, z) = tup;
Rust also supports direct access to a tuple element by using a period, ..
e.g) let six_point_four = tup.1;
Arrays also have a fixed length.
Every element of an array must have the same type.
The array is annotated with values of the same type inside square brackets.
e.g) let a: [i32; 5]
Array data are allocated on the stack.
An element of an array can be directly accessed with an index inside square brackets.
e.g) a[0]
Rust panics at index out of bounds in runtime.
Common Programming Concepts - Functions(2020-02-27):
Click to expand
Function definitions start with the fn keyword and have a set of parentheses after the function name.
Rust code uses snake case as the conventional style for function and variable names.
Rust doesn't care where functions are defined.
Functions can also be defined to have parameters, which are special variables that are part of a function's signature.
In function signatures, The type of each parameter must be declared.
Statements are instructions that perform some action and do not return a value.
e.g) let y = 6;, function definitions
Expressions evaluate to a resulting value.
Expressions do not include ending semicolons.
e.g) math operations, calling a function/macro, {}
The return value of a function must be declared with its type after ->.
It can be either using the return keyword or the final expression in the block to pass the return value.
Common Programming Concepts - Control Flow(2020-02-27):
Click to expand
An if expression allows to branch the code depending on conditions.
if expressions start with the keyword if, which is followed by a condition.
Conditions of if expressions must be provided as Boolean type.
Rust only executes the block for the first true condition.
It is more powerful to use match than using too many else if expressions.
Because if is an expression, it can be placed on the right side of a let statement.
e.g) let number = if condition { ... }
In this case, types of last expressions in if, else if, and else blocks must be equal.
Rust has three kinds of loops: loop, while, and for.
The loop keyword makes an infinite loop.
To break out of a loop, the break keyword must be placed.
The loop can also return values using the break expression.
The while loop has a condition, and it checks the condition by each loops until it became false.
Using for loop, it is able to loop through each element of a collection without consideration to the bound.
It is more safe to use for than to use while while looping through a collection.
Range is a type provided by the standard library.
It generates all numbers in sequence starting from one number and ending before another number.
e.g) (1..4)
Ownership(2020-03-07):
Click to expand
All data stored on the stack must have a known, fixed size.
Data with an unknown size at compile time or a size that might change must be stored on the heap.
An enough spot on the memory is allocated on the heap.
Ownership rules:
Each value in Rust has a variable that's called its owner.
There can only be one owner at a time.
When the owner goes out of scope, the value will be dropped.
A scope is the range within a program for which an item is valid.
The string type is stored on the heap.
String literals are stored on the stack.
e.g) let mut s = String::from("hello");
The double colon, ::, is an operator that allows to namespace methods under the type.
That kind of string can be mutated.
e.g) s.push_str(", world!");
The String type need to be allocated an amount of memory on the heap.
The memory must be requested from the OS at runtime.
This can be done by calling String::from.
This memory must be returned to the OS after use.
The memory is automatically returned once the variable goes out of scope.
When a String variable goes out of scope, Rust calls a drop function.
When assigning the stack data of a variable to another variable, Rust makes a copy of this value.
In case of the String type, Rust copies only pointers rather than values.
A String is made up of three parts, pointer, length, and capacity.
Rust does a shallow copy and also invalidates the first variable to avoid a double free error.
In other words, Rust moves the first variable to the second.
To copy the String deeply, use a common method called clone.
e.g) let _s = s.clone();
It's possible to return multiple values using a tuple.
e.g) (s, length)
Ownership - References and Borrowing(2020-03-12):
Click to expand
To prevent the ownership of a variable to be moved into a different scope, use a reference.
The ampersand, &, allows to refer to some value without taking ownership of it.
To dereference it, use the dereference operator, *.
Although the reference goes out of its scope, the variable is not dropped.
Setting references as function parameters is called borrowing.
The value of a reference can be modified only when the reference is set to be mutable.
There can be only one mutable reference of the variable at a time.
Rust can prevent data races in this fashion.
A data race happens when three behaviors occur:
Two or more pointers access the same data at the same time.
At least one of the pointers is being used to write to the data.
There's no mechanism being used to synchronize access to the data.
It is not possible to have a mutable reference while having an immutable one.
Multiple immutable references can exist simultaneously.
A reference's scope starts from where it is introduced and continues through the last time that it is used.
A dangling pointer is that references a location in memory that may have been given to someone else, by freeing some memory while preserving a pointer to that memory.
In Rust, the compiler guarantees that references will never be dangling references.
To do so, Rust introduced a new feature, lifetime.
Slices let you reference a contiguous sequence of elements in a collection rather than the whole collection.
The enumerate method returns a tuple that has an index and a reference of an item.
A string slice is a reference to part of a String.
e.g) let hello = &s[0..5];
String literals are also slices pointing to that specific point of the binary.
e.g) &str
Other slices work same as string slices.
Struct(2020-03-13):
Click to expand
To define a struct, write the keyword struct and name the entire struct.
Inside curly brackets, names and types of data being grouped together should be described.
To use a struct after defining it, create an instance of that struct by specifying concrete values for each of the fields.
Pairs of the field and the value will be assigned in this form key: value.
To get a specific value from a struct, use dot notation.