Dwarves
Memo
Type ESC to close search bar

Playaround With Rust

Mozilla intends to use Rust as a platform for prototyping experimental browser architectures.

Specifically, the hope is to develop a browser that is more amenable to safe and parallel than the existing ones, while also being less prone to common C++ coding errors.

What makes Rust special

Ownership

Let’s take this example:

let x = String::from("hello");

    let y = x;

It creates variable x in the stack, len 5, cap 5, ptr to heap contain content. When assigning y = x, Rust disable the x in the stack(no longer usable), and create new y have ptr to ptr of x

Let’s take another example

let x = 5;

let y = x;

x still usable after assign. The reason for that is an integer in Rust is saved in stack -> implemented Copy trait. The price of a copy in the stack does not as expensive as the other heap types(String).

Therefore, Rust let users do this by implement Copy trait for some types that save in stack(integer type, boolean type, floating-point type, character type, tuple that only contain above types). Other types that allocating memory in the heap when implementing Drop trait. That mean variables of that type will drop if out of scope. And if a user tries to implement Copy trait for this will raise compile-time error.

Immutable

Variables in Rust immutable by default, can not change throughout its lifetime. Thus, it resolves the problem of safety in Rust. If things are immutable by default, Rust compiler can easily pick up any side-affect, mutability during compile-time and guarantee application correctness.

Variable Declaration

Go

var x int // x = 0 -- a.k.a zero value

Rust

let x: i64 // x is un-addresable value, cannot be use util set x = somevalue

Expression-base language

Rust is primarily an expression language. This means that most forms of value-producing or effect-causing evaluation are directed by the uniform syntax category of expressions. Each kind of expression can typically nest within each other kind of expression, and rules for evaluation of expressions involve specifying both the value produced by the expression and the order in which its sub-expressions are themselves evaluated.

In contrast, statements in Rust serve mostly to contain and explicitly sequence expression evaluation.

Rust allow user do something like

let y = if x == 5 {  
    10 // y = 10           
 } else {     
    15 // y =15  
}

Lifetime

Because of the borrowing. The way Rust compiler check if you are trying to use a variable that borrowed by the other. Rust will compile this

fn main() {
    let x;
    {
        let y = 5;
        x= &y
    }
    println!("{}",x)
}

into this

fn main() {
   'a: {
        let x;
        'b: {
            let y = 5;// y have an amount of 'b lifetime(let say: 10 energy)
            x= &y// so y will be no longer valid when it out of energy
        }// when y go here, it runs out of energy <=> energy = 0
// therefore, Rust compiler can know that, oh, y is no longer exist 
// and then x trying to borrow it
// x is now borrowing from the deallocated memory
    println!("{}",x) 
   }
}

Hence, we can say, no matter what we do with borrowing, Rust must know the lifetime of parameter, it we don’t provide it, Rust stopping what you do by the error: missing lifetime specifier.**

E.g: When you are trying to put the function parameter by borrow some variable, or trying to borrow the function parameter inside function, Rust need to know the lifetime of it, otherwise, Rust compiler will stopping by the error

fn largest(x: &i64,y: &i64) -> &i64 {
    if x > y {
        x
    } else {
        y
    }
}

fn main() {
        let x;
        {
            let y = 5; 
            x = &y;
            println!("{}", largest(&x, &y))
        }
}

In order to correct the function, we just put the lifetime in parameter like:

fn largest(x: &i64, y: &i64) -> &i64 {
   if x > y {
       x
   } else {
       y
   }
}