Por Que Rust

Me

A languagem mais amada segundo o StackOverflow Survey 2019

... pelo 4⁰ ano seguido.

Imutabilidade por Default


fn main() {
    let a = 2;
    a = 3;
    println!("{}", a);
}
                        

3 |     let a = 2;
  |         -
  |         |
  |         first assignment to `a`
  |         help: make this binding mutable: `mut a`
4 |     a = 3;
  |     ^^^^^ cannot assign twice to immutable variable
                        

fn main() {
    let mut a = 2;
    a = 3;
    println!("{}", a);
}
                        

Borrow Checker


a = String::from("hello");
                        
"Variável a tem o valor "hello""
"Posição de memória apontada por a tem o valor "hello""

0x3f5cbf89 = "hello"
                            
A language that doesn't affect the way you think about programming, is not worth knowing.
-- Alan Perlis, "ALGOL"

fn main() {
    let a = String::from("hello");
    let _b = a;
    println!("{}", a)
}
                        

error[E0382]: borrow of moved value: `a`
 --> src/main.rs:5:20
  |
4 |     let _b = a;
  |              - value moved here
5 |     println!("{}", a)
  |                    ^ value borrowed here after move
  |
  = note: move occurs because `a` has type `std::string::String`, which does not implement the `Copy` trait
                        

E se eu precisar acessar a variável em mais de um lugar?

References


fn main() {
    let a = String::from("hello");
    let _b = &a;
    println!("{}", a)
}
                        

Regras do Borrow Checker

Uma região de memória tem apenas um dono.

A região é desalocada quando o dono sair de escopo.

Regras do Borrow Checker

Uma região de memória pode ter inifitas referências.

... desde que elas não durem mais do que o dono.

Regras do Borrow Checker

É possível ter uma referência mutável de uma região de memória.

... mas para haver uma referência mutável ela deve ser a única referência.

presente := Presente { ... }
canal <- presente
presente := Presente { ... }
canal <- presente
presente.abrir()
Swift 5 Exclusivity Enforcement

Tipos Algébricos

(structs)

struct


struct Present {
    package_color: String,
    content: String
}
                        

enum


enum IpAddr {
   V4,
   V6
}
                        

enum IpAddr {
    V4(String),
    V6(String),
}
                        

let home = IpAddr::V4(String::from("127.0.0.1");

match home {
    V4(address) => println!("IPv4 addr: {}", address),
    V6(address) => println!("Ipv6 addr: {}", address),
}
                        

enum Option<T> {
    Some(T),
    None
}
                        

Error Control


try:
    something()
except Exception:
    pass
                        

try {
   something();
} catch (Exception ex) {
   System.out.println(ex);
}
                        

FILE* f = fopen("someting.txt", "wb");
fprintf(f, "Done!");
fclose(f);
                        
Onde o erro foi tratado nisso?

enum Result<T, E> {
    Ok(T),
    Err(E),
}
                        

File::create("something.txt") match {
    Ok(fp) => fp.write_all(b"Hello world"),
    Err(err) => println!("Failure! {}", err),
}
                        

File::create("something.txt") match {
    Ok(fp) => fp.write_all(b"Hello world") match {
        Ok(_) => (),
        Err(err) => println!("Can't write! {}", err),
    }
    Err(err) => println!("Failure! {}", err),
}
                        

let mut file = File::create("something.txt").unwrap();
file.write(b"Hello world").unwrap();
                        

let mut file = File::create("something.txt")?;
file.write(b"Hello world")?;
OK(())
                        

Macros

Crazy stuff

How Rust’s standard library was vulnerable for years and nobody noticed
No, the problem isn’t “bad coders”
4.5k issues no Github
rustup
stable-x86_64-pc-windows-msvc
armv7-unknown-linux-gnueabihf
wasm32-unknown-unknown (WebAssembly)

Bibliotecas

Rayon


fn sum_of_squares(input: &[i32]) -> i32 {
    input.iter()
         .map(|&i| i * i)
         .sum()
}
                        

Rayon


fn sum_of_squares(input: &[i32]) -> i32 {
    input.par_iter()
         .map(|&i| i * i)
         .sum()
}
                        

Log-Derive


#[logfn(ok = "TRACE", err = "ERROR")]
fn call_isan(num: &str) -> Result<Success, Error> {
    if num.len() >= 10 && num.len() <= 15 {
        Ok(Success)
    } else {
        Err(Error)
    }
}
                        

E quem usa?

Magic Pocket

Dropbox

Petabyte storage

Servo

Mozilla

Base do Firefox Quantum

Azure

Microsoft

Usado na parte de IoT do Azure

Tor