Variable bindings

https://doc.rust-lang.org/reference/statements.html#let-statements

The let keyword creates a variable binding:

#![allow(unused)]
fn main() {
let x;   // declaration of x
x = 666; // assign value to x
}

You can also write this in a single line:

#![allow(unused)]
fn main() {
let x = 42;
}

In most cases, Rust can infer types for bindings, however, you can also specify it directly:

#![allow(unused)]
fn main() {
let x: char = 'a'; // a is a single unicode char

// Rust's primitive types are
// char and str for strings
// i8, i16, i32, i64, i128 for signed numbers
// u8, u16, u32, u64, u128 for unsigned
// f32, f64 for floating point
// bool
```;

It is forbidden to use unitialized, or even possibly-unitialized variables:

```rust
let x;
my_function(x); // error: use of possibly unitialized variable x
}

The underscore _ is a special identifier for throwing away/ignoring values:

#![allow(unused)]
fn main() {
let _ = "this string is thrown away and probably not even in the compiled binary";
}

You might also do this for functions that return something

#![allow(unused)]
fn main() {
let _ = my_function(); // return value thrown away
}

Prepending underscore to a binding name makes compiler ignore unused code warnings:

#![allow(unused)]
fn main() {
let _x = 'e'; // useful for in-progress code or some tricks
}

You can create a binding with the same name as a binding that already exists in the same scope. This is called "shadowing":

#![allow(unused)]
fn main() {
let x = 'a';
let x = 12 * 2; // shadowed bindings don't have to have the same type
}

Keep in mind that for as long as its needed, the first x also, so already existing references to it will stay valid

Rust has tuples, which are "fixed-length collections of values of different types":

#![allow(unused)]
fn main() {
let two = ("two", 2);
two.0; // "two"
two.1; // 2

Tuples can be destructured, that is, broken down to individual members:

let (two_string, two_num) = ("two", 2);
}

The semi-colon signifies the end of a statement:

#![allow(unused)]
fn main() {
let a = 1;
let b = 2;
let c = a - b * 2;
}

Variable bindings are immutable by default and cannot be assigned to a again. Use the mut keyword to make a binding mutable:

#![allow(unused)]
fn main() {
let mut x = 0;
x = 2;
x = 92391293;
}