diff --git a/_images/full-house-michelle-tanner.gif b/_images/full-house-michelle-tanner.gif new file mode 100644 index 0000000..4a3a6ca Binary files /dev/null and b/_images/full-house-michelle-tanner.gif differ diff --git a/_images/rust-issues.png b/_images/rust-issues.png index 8d2109f..f1be0c6 100644 Binary files a/_images/rust-issues.png and b/_images/rust-issues.png differ diff --git a/porque-rust.html b/porque-rust.html index 74565b5..2de1e42 100644 --- a/porque-rust.html +++ b/porque-rust.html @@ -72,372 +72,193 @@
- Basic (com números e estruturado), dBase III Plus, - Clipper, Pascal, Cobol, Delphi (ObjectPascal), - C, C++, ActionScript (Flash), PHP, JavaScript, - Python, Objective-C, Clojure, Java, Scala - , Rust. -
- - -- - A linguagem mais amada segundo o StackOverflow - Survey 2019 - - -
... pelo 4⁰ ano seguido.
- - - -Resultado final com performance semelhante ao C...
- - - - -... mas com abstrações em algo nível
- -
-fn main() -> u8 {
- let a = 2;
- a = 3;
- println!("{}", a);
- a
-}
-
-
- + Basic (com números e estruturado), dBase III Plus, + Clipper, Pascal, Cobol, Delphi (ObjectPascal), + C, C++, ActionScript (Flash), PHP, JavaScript, + Python, Objective-C, Clojure, Java, Scala + , Rust. +
- Uma outra forma de escrever o let seria: + -
-3 | let a = 2;
- | -
- | |
- | first assignment to `a`
- | help: make this binding mutable: `mut a`
-4 | a = 3;
- | ^^^^^ cannot assign twice to immutable variable
-
+ - Perl
+ - Ruby
+ - Haskell
+ - Swift
+
+
-3 | let a = 2;
- | -
- | |
- | first assignment to `a`
- | help: make this binding mutable: `mut a`
-4 | a = 3;
- | ^^^^^ cannot assign twice to immutable variable
-
+
-3 | let a = 2;
- | -
- | |
- | first assignment to `a`
- | help: make this binding mutable: `mut a`
-4 | a = 3;
- | ^^^^^ cannot assign twice to immutable variable
-
+
+let a = String::from("hello");
+
+ a
tem o valor "hello"
"
- a
tem o valor "hello"
"
+
-let a = String::from("hello");
-
- a
tem o valor "hello"
"
-
- a
tem o valor "hello"
"
-
+
+
0x3f5cbf89 = "hello"
-
-
-
-
- Nunca uma linguagem me fez "despensar" no nome da
- variável pra pensar que ela representa, na verdade,
- uma posição de memória.
-
-
-
-
-
-
-
- É mais ou menos isso que Rust "pensa" internamente
- quando vê uma variável: uma posição de memória, de
- um tamanho já definido, de um tipo definido.
-
- E essa posição de memória *pertence* apenas à
- variável indicada.
-
-
-
-
-
+
+
fn main() {
let a = String::from("hello");
let _b = a;
println!("{}", a)
}
-
-
+
+
error[E0382]: borrow of moved value: `a`
--> src/main.rs:5:20
|
@@ -449,410 +270,413 @@ error[E0382]: borrow of moved value: `a`
= note: move occurs because `a` has type
`std::string::String`, which does not
implement the `Copy` trait
-
-
-
- O borrow checked não deixa a variável "a" ser
- utilizada: quando a atribuímos "_b" o valor de "a",
- o que estamos fazendo é indicando que aquela
- posição de memória agora é controlada por "_b" e
- não mais por "a".
-
-
+
- E se eu precisar acessar a variável em mais de um lugar?
+Para ter mais de um acesso a mesma posição de memória, referências
-
+
+
fn main() {
let a = String::from("hello");
let _b = &a;
println!("{}", a)
}
-
-
-
-
-
-
-
- Uma referência nada mais é que um ponteiro para um
- "controlador" de uma região de memória.
-
-
-
-
- Regras do Borrow Checker
-
-
- Uma região de memória tem apenas um dono.
-
-
-
- Passar um valor (região de memória) de uma variável
- para outra, troca o dono.
-
-
-
- A região é desalocada quando o dono sair de escopo.
-
-
-
- Uma coisa engraçada sobre "quando sair de escopo" é
- que existe uma função semelhante ao "free()" do C,
- chamada "drop". Essa função não tem nada no corpo,
- e recebe um parâmetro (sem ser por referência), se
- tornando a dona da memória; assim, como ela termina
- exatamente naquele ponto, a região de memória é
- liberada.
-
-
-
-
- Drop
-
-
+
+
+
+
+
+
+
+ Uma referência nada mais é que um ponteiro para um
+ "controlador" de uma região de memória.
+
+
+
+
+ Regras do Borrow Checker
+
+
+ Uma região de memória tem apenas um dono.
+
+
+
+ Passar um valor (região de memória) de uma variável
+ para outra, troca o dono.
+
+
+
+ A região é desalocada quando o dono sair de escopo.
+
+
+
+ Uma coisa engraçada sobre "quando sair de escopo" é
+ que existe uma função semelhante ao "free()" do C,
+ chamada "drop". Essa função não tem nada no corpo,
+ e recebe um parâmetro (sem ser por referência), se
+ tornando a dona da memória; assim, como ela termina
+ exatamente naquele ponto, a região de memória é
+ liberada.
+
+
+
+
+ Drop
+
+
pub fn drop<T>(_x: T) { }
-
-
-
-
- Regras do Borrow Checker
-
-
- Uma região de memória pode ter infinitas referências.
-
-
-
- ... desde que elas não durem mais do que o dono.
-
-
-
- Não é possível ter uma função que cria uma variável
- e retorna apenas uma referência para essa variável:
- no momento que a função for encerrada, ela irá
- levar todas as variáveis com ela e as referências
- se tornaram inválidas.
-
-
-
-
- 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.
-
-
-
-
-
-
-
- E o que isso ajuda, no final das contas?
-
-
-
-
-
-
-
-
- Microsoft: 70 percent of all security bugs are memory safety issues
-
-
-
-
- Swift 5 Exclusivity Enforcement
-
-
-
- A ideia do borrow checker é tão interessante que
- até o Swift 5 agora tem o seu próprio borrow
- checker (com outro nome, mas o princípio da coisa é
- basicamente o mesmo, apesar de ser um pouco mais
- leve no Swift).
-
-
-
- Verona: Research programming language for concurrent ownership
-
-
-
-
- 5. Tipos Algébricos
-
-
-
- enum
-
-enum IpAddr {
- V4,
- V6
-}
-
-
-
-
-
-enum IpAddr {
- V4(String),
- V6(String),
-}
-
-
+
+
-let home = IpAddr::V4(String::from("127.0.0.1"));
+
+ Regras do Borrow Checker
-match home {
- V4(address) => println!("IPv4 addr: {}", address),
- V6(address) => println!("Ipv6 addr: {}", address),
-}
-
-
-try:
- something()
-except Exception:
- pass
-
-
-var obj = null;
-try {
- obj = get_object();
-} catch (Exception ex) {
- System.out.println(ex);
-}
-obj.do_something();
-
-
-FILE* f = fopen("someting.txt", "wb");
-fprintf(f, "Done!");
-fclose(f);
-
-
-enum Result<T, E> {
- Ok(T),
- Err(E),
-}
-
- + Uma região de memória pode ter infinitas referências. +
-
-match File::create("something.txt") {
- Ok(fp) => fp.write_all(b"Hello world"),
- Err(err) => println!("Failure! {}", err),
-}
-
- + ... desde que elas não durem mais do que o dono. +
-
-match File::create("something.txt") {
- Ok(fp) => match fp.write_all(b"Hello world") {
- 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")
- .expect("ERROR OPENING");
-file.write(b"Hello world")
- .expect("ERROR WRITING");
-
-
-let mut file = File::create("something.txt")?;
-file.write(b"Hello world")?;
-OK(())
-
+ + É 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. +
-struct Gift {
- package_color: String,
- content: String
-}
-
-
-
-let presente = Gift { package_color: "red", content: "A GIFT!" };
-
-
-struct Point<T> {
- x: T,
- y: T
+
+
+
+
+
+ Microsoft: 70 percent of all security bugs are memory safety issues
+
+
+
+ Regras do Borrow Checker
+
+ Uma região de memória tem apenas um dono.
+
+ Passar um valor (região de memória) de uma variável
+ para outra, troca o dono.
+
+ Sem condições de corrida (race conditions)
+
+
+
+ Regras do Borrow Checker
+
+ A região é desalocada quando o dono sair de escopo.
+
+
+ Evita problemas de double-free ou não usar free e sem
+ precisar de garbage collector.
+
+
+
+
+ Regras do Borrow Checker
+
+
+ Uma região de memória pode ter infinitas referências.
+ ... desde que elas não durem mais do que o dono.
+
+
+
+ Sem dangling-pointers.
+
+
+
+
+ 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.
+
+
+ Condição de corrida
+
+
+
+ Além do borrow Checker
+
+
+ - Uso extenso de iteradores para evitar out-of-bounds.
+ - Bound-check para casos sem iteradores (com custo).
+ - Sem coerção de tipos.
+
+
+
+
+ MISRA-C / MISRA-C++
+
+ Conjunto de regras para uso de C/C++ para equipamentos
+ aonde vidas humanas estão em jogo.
+
+ 75% das regras já são obrigatórias pelo
+ compilador (108 dos 141 casos)
+
+
+
+
+
+
+
+ A Linguagem Mais Amada
+
+
+ A linguagem mais amada segundo o StackOverflow
+ Survey 2022
+
+
+
+ ... pelo 7⁰ ano seguido.
+
+
+ O resultado do StackOverflow é sobre qual
+ linguagem os programadores realmente gostam de
+ programar (e quais eles tem pavor de usar).
+
+ Pessoalmente, depois de 30 anos programando,
+ quando começei a brincar com Rust, eu
+ finalmente me diverti enquanto programava.
+
+
+
+
+ Green Energy Language
+
+
+
+
+ Num estudo sobre quais linguagens consomem mais
+ energia, Rust chegou bem próximo de C.
+
+ Parte do trabalho de otimização do Rust vem da LLVM
+ (parte do pacote do Clang), mas a árvore de
+ abstração ainda é gerada pela linguagem -- o que
+ significa que o compilador Rust consegue "ajudar" o
+ LLVM a otimizar o código.
+
+
+
+
+
+ Compilador Chato mas Amigável
+
+
+
+
+fn main() -> u8 {
+ let a = 2;
+ a = 3;
+ println!("{}", a);
}
-
-
+
+
+
-let my_point = Point<f32>(x: 1.0, y: 2.0);
-
+ Uma outra forma de escrever o let seria:
-
-let my_point = Point(x: 1.0, y: 2.0);
+ ```
+ let a: u8 = 2;
+ ```
+
+3 | let a = 2;
+ | -
+ | |
+ | first assignment to `a`
+ | help: make this binding mutable: `mut a`
+4 | a = 3;
+ | ^^^^^ cannot assign twice to immutable variable
-
+
+
+3 | let a = 2;
+ | -
+ | |
+ | first assignment to `a`
+ | help: make this binding mutable: `mut a`
+4 | a = 3;
+ | ^^^^^ cannot assign twice to immutable variable
+
+
+
+ ... mas se tu olhar com calma, tu vai ver que não só o
+ compilador disse, claramente, o que era o problema...
+
+
+
+
+
+3 | let a = 2;
+ | -
+ | |
+ | first assignment to `a`
+ | help: make this binding mutable: `mut a`
+4 | a = 3;
+ | ^^^^^ cannot assign twice to immutable variable
+
+
+
+ ... como também vai dizer como resolver o problema.
+
+
+
+
+
+
+
+ Ou seja, o compilador não só vai lá e diz: ERRADO!
+
+ ... ele ainda dá uma dica de como resolver esse
+ problema.
+
+
+
+
+ Verificar Erros é Obrigatório
+
+
+
+
enum Result<T, E> {
Ok(T),
Err(E),
}
-
-
-
-
- Traits
-
-
-trait Summary {
- fn summarize(&self) -> String;
-}
-
-
-
-
- Traits
+
+
-struct Phrase {
- phrase: String
+
+
+match File::create("something.txt") {
+ Ok(fp) => fp.write_all(b"Hello world"),
+ Err(err) => println!("Failure! {}", err),
}
+
+
-impl Summary for Phrase {
- fn summarize(&self) -> String {
- self.phrase
- .split_whitespace()
- .map(|word| word.chars().nth(0).unwrap())
- .collect()
+
+
+match File::create("something.txt") {
+ Ok(fp) => match fp.write_all(b"Hello world") {
+ Ok(_) => (),
+ Err(err) => println!("Can't write! {}", err),
}
+ Err(err) => println!("Failure! {}", err),
}
-
-
-
-
- Traits
-
-
-fn get_summary<T>(summarizable: T) -> String
- where T: Summary
-{
- ...
-}
-
+
-
+let mut file = File::create("something.txt").unwrap();
+file.write(b"Hello world").unwrap();
+
+ "Cargo is the Rust package manager"
+
+let mut file = File::create("something.txt")?;
+file.write(b"Hello world")?;
+OK(())
+
+ - "Cargo downloads your Rust package’s dependencies, - compiles your packages, makes distributable - packages, and uploads them to crates.io, the Rust - community’s package registry." -
+"Cargo is the Rust package manager"
+ ++ "Cargo downloads your Rust package’s dependencies, + compiles your packages, makes distributable + packages, and uploads them to crates.io, the Rust + community’s package registry." +
+
#[cfg(test)]
mod tests {
#[test]
fn testing() {
}
}
-
-
+
$ cargo test
Compiling adder v0.1.0 (file:///projects/adder)
Finished dev [unoptimized + debuginfo] target(s) in 0.22 secs
@@ -860,62 +684,12 @@ $ cargo test
running 1 test
test tests::testing ... ok
-
-
-#[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)
- }
-}
-
-