# 2. Structure of Rust From now on we are going to be mainly using this doc as a reference: [Link](https://doc.rust-lang.org/rust-by-example/index.html). This is a very useful document that teaches us how to use Rust by examples. There are certain elements to Rust that is different than traditional languages. We are going to talk about some of the more notable parts of them. ## Macros One of the important concepts in Rust are macros. As we saw in the previous post, anything ending with a ! is a macro. There are certain macros built in such as println!, but we can also create our own macros. For example: ``` // This is a simple macro named `say_hello`. macro_rules! say_hello { // `()` indicates that the macro takes no argument. () => { // The macro will expand into the contents of this block. println!("Hello!"); }; } fn main() { // This call will expand into `println!("Hello");` say_hello!() } ``` In the above example we create a macro called say_hello that will print Hello! when it is run. We can have macros that takes in arguments or ones that can be run without arguments. This is very useful if we want to create certain macros for code we know we are going to be running a lot throughout our code. ## Ownership Ownership is a very important aspect of Rust. While most languages have garbage collection or some other way of managing memory, Rust does not. Instead, Rust uses a system called ownership. This approach works by having a single owner of a piece of data. This owner can then pass ownership to another owner. By running a system of ownership minimizes duplication and cleaning up unused data. So for example let's take this code: ``` let s1 = String::from("hello"); let s2 = s1; println!("{}, world!", s1); ``` This code will not compile because we have assigned s2 to s1. This means that s1 is no longer valid. If we want to use s1 we would have to do something like this: ``` let s1 = String::from("hello"); let s2 = s1.clone(); println!("{}, world!", s1); ``` This will work because we are cloning s1 and assigning it to s2. This means that s1 is still valid and the items in s1 are copied to s2. This basic example is a very simple example of ownership. ## Borrowing (References) References are in a lot of ways similar to pointers in C. They allow us to access data without taking ownership of it. This is useful if we want to use a variable but not take ownership of it. But unlike C, Rust has certain rules that make it more memory safe. For example, you can differentiate mutable and immutable by using $x or $mut x. we can't have a mutable reference and an immutable reference at the same time. This is because we could have a situation where we have a mutable reference and then we try to use an immutable reference. This would cause a problem because the immutable reference would be trying to access data that is being changed by the mutable reference. This is a very common problem in C and Rust tries to avoid it. ## Lifetimes In rust every variable has a lifetime. This is the time that the variable is valid. This is important because we can't have a reference to a variable that is no longer valid. Lifetimes are a way of making sure that we don't have any dangling references. This can best be explained by an example: ``` fn main() { let i = 3; // Lifetime for `i` starts. ────────────────┐ // │ { // │ let borrow1 = &i; // `borrow1` lifetime starts. ──┐│ // ││ println!("borrow1: {}", borrow1); // ││ } // `borrow1 ends. ──────────────────────────────────┘│ // │ // │ { // │ let borrow2 = &i; // `borrow2` lifetime starts. ──┐│ // ││ println!("borrow2: {}", borrow2); // ││ } // `borrow2` ends. ─────────────────────────────────┘│ // │ } // Lifetime ends. ─────────────────────────────────────┘ ``` As seen above after the borrowed variable is called, the lifetime of the variable ends. This means that we can't have a reference to a variable that is no longer valid. ## [Continue to next section...](https://hackmd.io/@parsa-cu/rust-part-3)