RUST LANG

Nelson Corrêa Viana Júnior
@nelsonjr
github.com/ircnelson
Rust é uma linguagem de programação.
Está na categoria de system languages, multi-paradigma e compilada. Desenvolvida pela Mozilla Research.
A linguagem apareceu como um projeto pessoal de Graydon Hoare, funcionário da Mozilla.
Rust 1.0, a primeira versão estável, foi lançada em 15 de Maio de 2015.
A filosofia do Rust é: “Estável, mas nunca estagnado”. - Versão estável a cada 6 semanas.

O que é Rust?

Por que?
Onde usar?
Onde não usar?
Quem usa em produção?
Empresa | Projeto |
---|---|
Mozilla | Servo (Browser Engine integrado ao Firefox) |
Coursera | Ferramentas para provisionamento do ambiente Docker de produção |
Chef | Implementação do Delivery CLI |
Canonical | Monitoramento de servidores |
NPM | Mudaram de C para Rust em pontos críticos na arquitetura dos serviços de registry |
Dropbox | Otimização do cloud storage |
Ceph (Storage) |

Environment / Tooling
rustc | Compilador ex: rustc main.rs |
rustup | Gerenciador de versões do compilador ex: rustup update stable/beta/nightly |
cargo | Gerenciador de pacotes ex: cargo install nome_do_pacote cargo run cargo build cargo new cargo doc cargo test cargo bench |


- Memory safety
- Não possui Garbage Collector!
- Imutável por padrão
- Move semantics
- Concorrência sem data race
- Inferência de tipo
Características

Memory safety sem Garbage Collector?

GARBAGE COLLECTOR
Não usa destruição determinística; |
Exige muito recurso de memória pra poder ser eficiente (muitas vezes mais do que o seu próprio programa); |
As pausas do GC não são aceitáveis para sistemas realtime; |


OWNERSHIP
SHARED BORROW
SHARED MUTABLE BORROW

OWNERSHIP
Regras
- Cada recurso no Rust tem uma variável chamada de owner.
- Um recurso pode ter somente um owner por vez.
- Quando um owner sai do escopo, o recurso será destruído (dropped).
fn main() {
let say_hello = "hello world"; // 'say_hello' é valido daqui pra frente
println!("{}", say_hello);
} // 'say_hello' será liberado da memória

OWNERSHIP
fn main() {
let s1 = String::from("hello");
say_something(s1);
say_something(s1); // error!
}
fn say_something(text : String) {
// ^
// |______________ move ownership
println!("{}", text);
} // 'text' será liberado da memória


OWNERSHIP
fn main() {
let s1 = String::from("hello");
let s2 = say_something(s1);
say_something(s2);
}
fn say_something(text : String) -> String {
println!("{}", text);
text
}
Solução 1
Solução cheia de cerimonia.
Insustentável ao longo do software.

OWNERSHIP
fn main() {
let s1 = String::from("hello");
let s2 = s1.clone();
say_something(s1);
say_something(s2);
}
fn say_something(text : String) {
println!("{}", text);
} // 'text' será liberado da memória

Solução 2
Solução cara demais.
Todos os valores da Stack e Heap são clonados.

OWNERSHIP
fn main() {
let n1 = 5;
do_something(n1);
do_something(n1);
}
fn do_something(n : i32) {
println!("{}", n);
} // 'n' será liberado da memória
?
O que vai acontecer?

OWNERSHIP
fn main() {
let n1 = 5;
do_something(n1);
do_something(n1);
}
fn do_something(n : i32) {
println!("{}", n);
} // 'n' será liberado da memória
Tipos numéricos implementam
`Copy` trait por padrão.

SHARED BORROW (&)
fn main() {
let s1 = String::from("hello");
say_something(&s1);
say_something(&s1);
}
fn say_something(s : &String) {
println!("{}", s);
} // 's' será liberado da memória


SHARED BORROW (&)
fn main() {
let s1 = String::from("hello");
change(&s1);
}
fn change(s : &String) {
println!("{}", s);
s.push_str(" world"); // error!
}
error: cannot borrow immutable borrowed content `*s` as mutable
--> src/main.rs:10:5
|
6 | fn change(s : &String) {
| ------- use `&mut String` here to make mutable
...
10 | s.push_str(" world"); // error!
| ^ cannot borrow as mutable
Shared borrow não é sinônimo de mutabilidade.

SHARED MUTABLE BORROW (&mut)
Esta regra previne data race em tempo de compilação.
Data race ocorre quando os três comportamentos abaixo ocorre:
-
Dois ou mais ponteiros acessam o mesmo dado ao mesmo tempo.
-
Pelo menos um dos ponteiros está sendo usado para gravar os dados.
-
Não há nenhum mecanismo sendo usado para sincronizar o acesso aos dados.
Regra: Só pode existir uma referência mutável para o mesmo recurso no escopo.

SHARED MUTABLE BORROW (&mut)
fn main() {
let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s;
}
error[E0499]: cannot borrow `s` as mutable more than once at a time
--> src/main.rs:4:19
|
3 | let r1 = &mut s;
| - first mutable borrow occurs here
4 | let r2 = &mut s;
| ^ second mutable borrow occurs here
5 | }
| - first borrow ends here
Regra: Só pode existir uma referência mutável para o mesmo recurso no escopo.

SHARED MUTABLE BORROW (&mut)
fn main() {
let mut s1 = String::from("hello");
change(&mut s1);
println!("{}", s1);
}
fn change(s : &mut String) {
println!("{}", s);
s.push_str(" world");
}
Resolvendo o código da função 'change' usada no tópico de 'Shared borrow'.

https://rust-lang.github.io/book/second-edition
https://doc.rust-lang.org/book
http://science.raphael.poss.name/rust-for-functional-programmers.html
https://bryce.fisher-fleig.org
http://stackoverflow.com/questions/31949579/understanding-pointer-types-in-rust
https://www.youtube.com/watch?v=d1uraoHM8Gg
https://github.com/search?l=Rust&q=rust&type=Repositories&utf8=✓
http://arthurtw.github.io/2014/11/30/rust-borrow-lifetimes.html
irc.mozilla.org - #rust, #rust-beginners
Referências

Obrigado!
Rust Lang
By nelson correa v. júnior
Rust Lang
- 1,047