|
|
|
@ -99,17 +99,6 @@
|
|
|
|
|
</div> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<div> |
|
|
|
|
<ul> |
|
|
|
|
<li>Coordenador do meetup <strong>Rust in POA</strong></li> |
|
|
|
|
<li>Co-coordenador do meetup <strong>PyTche</strong></li> |
|
|
|
|
<li>Co-coordenador do meetup <strong>Design de Código</strong></li> |
|
|
|
|
<li>Palestrante do <strong>Tchelinux</strong></li> |
|
|
|
|
</ul> |
|
|
|
|
</div> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<div> |
|
|
|
|
<h3>JulioBiason.me</h3> |
|
|
|
@ -131,13 +120,13 @@
|
|
|
|
|
<li>Criada em 2006 por Graydon Hoare.</li> |
|
|
|
|
<li>Patrocinada pela Mozilla em 2009.</li> |
|
|
|
|
<li>Versão 1.0 em 2015.</li> |
|
|
|
|
<li>Versão atual: 1.41.1</li> |
|
|
|
|
<li>Versão atual: 1.70</li> |
|
|
|
|
</ul> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
Parte burocrática da apresentação. |
|
|
|
|
|
|
|
|
|
PS: Pode ser que, quando você essa apresentação, 1.38 |
|
|
|
|
PS: Pode ser que, quando você essa apresentação, 1.70 |
|
|
|
|
não seja mais a versão atual; a cada 6 semanas, sai uma |
|
|
|
|
nova versão do compilador. |
|
|
|
|
</aside> |
|
|
|
@ -171,15 +160,6 @@
|
|
|
|
|
</aside> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<img src="_images/my_opinion.jpg" alt=""> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
Alerta: Tudo aqui é a minha opinião sobre Rust e o |
|
|
|
|
contexto geral de linguagens de programação. |
|
|
|
|
</aside> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<div> |
|
|
|
|
A language that doesn't affect the way you think |
|
|
|
@ -204,170 +184,11 @@
|
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h2>1. A Linguagem Mais Amada</h2> |
|
|
|
|
<p> |
|
|
|
|
<a href="https://insights.stackoverflow.com/survey/2019"> |
|
|
|
|
A linguagem mais amada segundo o StackOverflow |
|
|
|
|
Survey 2019 |
|
|
|
|
</a> |
|
|
|
|
|
|
|
|
|
<p class="fragment">... pelo 4⁰ ano seguido.</p> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
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. |
|
|
|
|
</aside> |
|
|
|
|
</p> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h2>2. "Low Level Language with High Level Abstractions"</h2> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<p>Resultado final com performance semelhante ao C...</p> |
|
|
|
|
|
|
|
|
|
<img src="_images/rust-energy.png" alt=""> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
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. |
|
|
|
|
</aside> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<p>... mas com abstrações em algo nível</p> |
|
|
|
|
|
|
|
|
|
<ul> |
|
|
|
|
<li>Strings sem tamanho fixo</li> |
|
|
|
|
<li>Listas</li> |
|
|
|
|
<li>Mapas</li> |
|
|
|
|
</ul> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
Ao contrário de C, em que só se mexe com ponteiros |
|
|
|
|
pra cima e pra baixo, Rust tem todas as abstrações |
|
|
|
|
de alto nível que estamos acostumados com outras |
|
|
|
|
linguagens. |
|
|
|
|
|
|
|
|
|
Honestamente, se surgir uma nova linguagem que |
|
|
|
|
tenha mais proteções de memória, com performance |
|
|
|
|
ainda melhor que C mas eu tiver que escrever uma |
|
|
|
|
lista encadeada mais uma vez, eu destruo todas as |
|
|
|
|
coisas tecnológicas ao meu redor... |
|
|
|
|
|
|
|
|
|
E vou plantar batata. |
|
|
|
|
|
|
|
|
|
... porque aprendemos absolutamente NADA sobre |
|
|
|
|
desenvolvimento. |
|
|
|
|
</aside> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h2>3. Compilador Chato mas Amigável</h2> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
fn main() -> u8 { |
|
|
|
|
let a = 2; |
|
|
|
|
a = 3; |
|
|
|
|
println!("{}", a); |
|
|
|
|
a |
|
|
|
|
} |
|
|
|
|
</code></pre> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
Primeiro contato com Rust: assim como C, tem uma |
|
|
|
|
função `main`, que pode retornar um inteiro; para |
|
|
|
|
atribuir variáveis, usa-se `let`. |
|
|
|
|
|
|
|
|
|
Uma coisa: Rust é "strong and statically typed", o |
|
|
|
|
que sigifnica que a linguagem tem tipos, mas por |
|
|
|
|
padrão o compilador tenta inferir o tipo. |
|
|
|
|
|
|
|
|
|
Uma outra forma de escrever o let seria: |
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
let a: u8 = 2; |
|
|
|
|
``` |
|
|
|
|
</aside> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<pre><code class="hljs" data-trim> |
|
|
|
|
3 | let a = 2; |
|
|
|
|
| - |
|
|
|
|
| | |
|
|
|
|
| first assignment to `a` |
|
|
|
|
| help: make this binding mutable: `mut a` |
|
|
|
|
4 | a = 3; |
|
|
|
|
| ^^^^^ cannot assign twice to immutable variable |
|
|
|
|
</code></pre> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
Se você tentar mudar um dado depois de criado, o |
|
|
|
|
compilador Rust não vai deixar. |
|
|
|
|
</aside> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<pre><code class="hljs" data-trim data-line-numbers="7"> |
|
|
|
|
3 | let a = 2; |
|
|
|
|
| - |
|
|
|
|
| | |
|
|
|
|
| first assignment to `a` |
|
|
|
|
| help: make this binding mutable: `mut a` |
|
|
|
|
4 | a = 3; |
|
|
|
|
| ^^^^^ cannot assign twice to immutable variable |
|
|
|
|
</code></pre> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
... mas se tu olhar com calma, tu vai ver que não só o |
|
|
|
|
compilador disse, claramente, o que era o problema... |
|
|
|
|
</aside> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section data-transition="fade"> |
|
|
|
|
<pre><code class="hljs" data-trim data-line-numbers="5"> |
|
|
|
|
3 | let a = 2; |
|
|
|
|
| - |
|
|
|
|
| | |
|
|
|
|
| first assignment to `a` |
|
|
|
|
| help: make this binding mutable: `mut a` |
|
|
|
|
4 | a = 3; |
|
|
|
|
| ^^^^^ cannot assign twice to immutable variable |
|
|
|
|
</code></pre> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
... como também vai dizer como resolver o problema. |
|
|
|
|
</aside> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<img class="stretch" src="_images/Sorry-bout-that.gif" alt=""> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
Ou seja, o compilador não só vai lá e diz: ERRADO! |
|
|
|
|
|
|
|
|
|
... ele ainda dá uma dica de como resolver esse |
|
|
|
|
problema. |
|
|
|
|
</aside> |
|
|
|
|
<h2>O Que Rust Tem de Diferente?</h2> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h2>4. Borrow Checker</h2> |
|
|
|
|
<h2>Borrow Checker</h2> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
O "Borrow Checker" é uma das principais novidades |
|
|
|
@ -386,7 +207,7 @@ let a = String::from("hello");
|
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
"Variável <code>a</code> tem o valor <code>"hello"</code>" |
|
|
|
|
"Variável <strong><code>a</code></strong> tem o valor <strong><code>"hello"</code></strong>" |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
Em todas as linguagens que eu usei, sempre que via |
|
|
|
@ -397,7 +218,7 @@ let a = String::from("hello");
|
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<div> |
|
|
|
|
"Posição de memória apontada por <code>a</code> tem o valor <code>"hello"</code>" |
|
|
|
|
"Posição de memória apontada por <strong><code>a</code></strong> tem o valor <strong><code>"hello"</code></strong>" |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="fragment"> |
|
|
|
@ -461,9 +282,7 @@ error[E0382]: borrow of moved value: `a`
|
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<p>E se eu precisar acessar a variável em mais de um lugar?</p> |
|
|
|
|
|
|
|
|
|
<h3 class="fragment">References</h3> |
|
|
|
|
<p>Para ter mais de um acesso a mesma posição de memória, <strong>referências</strong></p> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
Assim como C++, Rust tem o conceito de "referências". |
|
|
|
@ -574,202 +393,212 @@ pub fn drop<T>(_x: T) { }
|
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<p> |
|
|
|
|
<a href="https://swift.org/blog/swift-5-exclusivity/">Swift 5 Exclusivity Enforcement</a> |
|
|
|
|
</p> |
|
|
|
|
<h3>Regras do Borrow Checker</h3> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
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). |
|
|
|
|
</aside> |
|
|
|
|
<p>Uma região de memória tem apenas um dono.</p> |
|
|
|
|
|
|
|
|
|
<p> |
|
|
|
|
<a href="https://github.com/microsoft/verona">Verona: Research programming language for concurrent ownership</a> |
|
|
|
|
</p> |
|
|
|
|
</section> |
|
|
|
|
<p>Passar um valor (região de memória) de uma variável |
|
|
|
|
para outra, troca o dono.</p> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h2>5. Tipos Algébricos</h2> |
|
|
|
|
<p class="fragment"><strong>Sem condições de corrida (race conditions)</strong></p> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h3>enum</h3> |
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
enum IpAddr { |
|
|
|
|
V4, |
|
|
|
|
V6 |
|
|
|
|
} |
|
|
|
|
</code></pre> |
|
|
|
|
</section> |
|
|
|
|
<h3>Regras do Borrow Checker</h3> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
enum IpAddr { |
|
|
|
|
V4(String), |
|
|
|
|
V6(String), |
|
|
|
|
} |
|
|
|
|
</code></pre> |
|
|
|
|
<p>A região é desalocada quando o dono sair de escopo.</p> |
|
|
|
|
|
|
|
|
|
<p class="fragment"><strong> |
|
|
|
|
Evita problemas de double-free ou não usar free e sem |
|
|
|
|
precisar de garbage collector. |
|
|
|
|
</strong></p> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
let home = IpAddr::V4(String::from("127.0.0.1")); |
|
|
|
|
<h3>Regras do Borrow Checker</h3> |
|
|
|
|
|
|
|
|
|
match home { |
|
|
|
|
V4(address) => println!("IPv4 addr: {}", address), |
|
|
|
|
V6(address) => println!("Ipv6 addr: {}", address), |
|
|
|
|
} |
|
|
|
|
</code></pre> |
|
|
|
|
<p> |
|
|
|
|
Uma região de memória pode ter infinitas referências. |
|
|
|
|
... desde que elas não durem mais do que o dono. |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<p class="fragment"><strong> |
|
|
|
|
Sem dangling-pointers. |
|
|
|
|
</strong></p> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h2>6. Error Control</h2> |
|
|
|
|
<h3>Regras do Borrow Checker</h3> |
|
|
|
|
|
|
|
|
|
<p> |
|
|
|
|
É 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 <strong>única</strong> referência. |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<p class="fragment"><Strong>Condição de corrida</strong></p> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<pre><code class="hljs python" data-trim> |
|
|
|
|
try: |
|
|
|
|
something() |
|
|
|
|
except Exception: |
|
|
|
|
pass |
|
|
|
|
</code></pre> |
|
|
|
|
<h3>Além do borrow Checker</h3> |
|
|
|
|
|
|
|
|
|
<ul> |
|
|
|
|
<li>Uso extenso de iteradores para evitar out-of-bounds.</li> |
|
|
|
|
<li>Bound-check para casos sem iteradores (com custo).</li> |
|
|
|
|
<li>Sem coerção de tipos.</li> |
|
|
|
|
</ul> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<pre><code class="hljs java" data-trim> |
|
|
|
|
var obj = null; |
|
|
|
|
try { |
|
|
|
|
obj = get_object(); |
|
|
|
|
} catch (Exception ex) { |
|
|
|
|
System.out.println(ex); |
|
|
|
|
} |
|
|
|
|
obj.do_something(); |
|
|
|
|
</code></pre> |
|
|
|
|
<h3>MISRA-C / MISRA-C++</h3> |
|
|
|
|
|
|
|
|
|
<p>Conjunto de regras para uso de C/C++ para equipamentos |
|
|
|
|
aonde vidas humanas estão em jogo.</p> |
|
|
|
|
|
|
|
|
|
<p class="fragment">75% das regras já são obrigatórias pelo |
|
|
|
|
compilador (108 dos 141 casos)</p> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<pre><code class="hljs c" data-trim> |
|
|
|
|
FILE* f = fopen("someting.txt", "wb"); |
|
|
|
|
fprintf(f, "Done!"); |
|
|
|
|
fclose(f); |
|
|
|
|
</code></pre> |
|
|
|
|
<img src="_images/full-house-michelle-tanner.gif" alt="" class="stretch"> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<div> |
|
|
|
|
Onde o erro foi tratado nisso? |
|
|
|
|
</div> |
|
|
|
|
<h2>A Linguagem Mais Amada</h2> |
|
|
|
|
<p> |
|
|
|
|
<a href="https://insights.stackoverflow.com/survey/2019"> |
|
|
|
|
A linguagem mais amada segundo o StackOverflow |
|
|
|
|
Survey 2022 |
|
|
|
|
</a> |
|
|
|
|
</p> |
|
|
|
|
|
|
|
|
|
<p class="fragment">... pelo 7⁰ ano seguido.</p> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
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. |
|
|
|
|
</aside> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
enum Result<T, E> { |
|
|
|
|
Ok(T), |
|
|
|
|
Err(E), |
|
|
|
|
} |
|
|
|
|
</code></pre> |
|
|
|
|
<h2>Green Energy Language</h2> |
|
|
|
|
|
|
|
|
|
<img src="_images/rust-energy.png" alt=""> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
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. |
|
|
|
|
</aside> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
match File::create("something.txt") { |
|
|
|
|
Ok(fp) => fp.write_all(b"Hello world"), |
|
|
|
|
Err(err) => println!("Failure! {}", err), |
|
|
|
|
} |
|
|
|
|
</code></pre> |
|
|
|
|
<h2>Compilador Chato mas Amigável</h2> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
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), |
|
|
|
|
fn main() -> u8 { |
|
|
|
|
let a = 2; |
|
|
|
|
a = 3; |
|
|
|
|
println!("{}", a); |
|
|
|
|
} |
|
|
|
|
</code></pre> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
let mut file = File::create("something.txt").unwrap(); |
|
|
|
|
file.write(b"Hello world").unwrap(); |
|
|
|
|
</code></pre> |
|
|
|
|
</section> |
|
|
|
|
<aside class="notes"> |
|
|
|
|
Primeiro contato com Rust: assim como C, tem uma |
|
|
|
|
função `main`, que pode retornar um inteiro; para |
|
|
|
|
atribuir variáveis, usa-se `let`. |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
let mut file = File::create("something.txt") |
|
|
|
|
.expect("ERROR OPENING"); |
|
|
|
|
file.write(b"Hello world") |
|
|
|
|
.expect("ERROR WRITING"); |
|
|
|
|
</code></pre> |
|
|
|
|
</section> |
|
|
|
|
Uma coisa: Rust é "strong and statically typed", o |
|
|
|
|
que sigifnica que a linguagem tem tipos, mas por |
|
|
|
|
padrão o compilador tenta inferir o tipo. |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
let mut file = File::create("something.txt")?; |
|
|
|
|
file.write(b"Hello world")?; |
|
|
|
|
OK(()) |
|
|
|
|
</code></pre> |
|
|
|
|
</section> |
|
|
|
|
Uma outra forma de escrever o let seria: |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h2>7. Generics/Traits</h2> |
|
|
|
|
``` |
|
|
|
|
let a: u8 = 2; |
|
|
|
|
``` |
|
|
|
|
</aside> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h3>Structs</h3> |
|
|
|
|
|
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
struct Gift { |
|
|
|
|
package_color: String, |
|
|
|
|
content: String |
|
|
|
|
} |
|
|
|
|
<pre><code class="hljs" data-trim> |
|
|
|
|
3 | let a = 2; |
|
|
|
|
| - |
|
|
|
|
| | |
|
|
|
|
| first assignment to `a` |
|
|
|
|
| help: make this binding mutable: `mut a` |
|
|
|
|
4 | a = 3; |
|
|
|
|
| ^^^^^ cannot assign twice to immutable variable |
|
|
|
|
</code></pre> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
Structs em Rust são basicamente o mesmo que em C. |
|
|
|
|
Se você tentar mudar um dado depois de criado, o |
|
|
|
|
compilador Rust não vai deixar. |
|
|
|
|
</aside> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h3>Structs</h3> |
|
|
|
|
|
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
let presente = Gift { package_color: "red", content: "A GIFT!" }; |
|
|
|
|
<pre><code class="hljs" data-trim data-line-numbers="7"> |
|
|
|
|
3 | let a = 2; |
|
|
|
|
| - |
|
|
|
|
| | |
|
|
|
|
| first assignment to `a` |
|
|
|
|
| help: make this binding mutable: `mut a` |
|
|
|
|
4 | a = 3; |
|
|
|
|
| ^^^^^ cannot assign twice to immutable variable |
|
|
|
|
</code></pre> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
... mas se tu olhar com calma, tu vai ver que não só o |
|
|
|
|
compilador disse, claramente, o que era o problema... |
|
|
|
|
</aside> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h3>Structs Genéricas</h3> |
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
struct Point<T> { |
|
|
|
|
x: T, |
|
|
|
|
y: T |
|
|
|
|
} |
|
|
|
|
<section data-transition="fade"> |
|
|
|
|
<pre><code class="hljs" data-trim data-line-numbers="5"> |
|
|
|
|
3 | let a = 2; |
|
|
|
|
| - |
|
|
|
|
| | |
|
|
|
|
| first assignment to `a` |
|
|
|
|
| help: make this binding mutable: `mut a` |
|
|
|
|
4 | a = 3; |
|
|
|
|
| ^^^^^ cannot assign twice to immutable variable |
|
|
|
|
</code></pre> |
|
|
|
|
|
|
|
|
|
<aside class="notes"> |
|
|
|
|
... como também vai dizer como resolver o problema. |
|
|
|
|
</aside> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h3>Structs Genéricas</h3> |
|
|
|
|
<img class="stretch" src="_images/Sorry-bout-that.gif" alt=""> |
|
|
|
|
|
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
let my_point = Point<f32>(x: 1.0, y: 2.0); |
|
|
|
|
</code></pre> |
|
|
|
|
<aside class="notes"> |
|
|
|
|
Ou seja, o compilador não só vai lá e diz: ERRADO! |
|
|
|
|
|
|
|
|
|
<pre><code class="hljs rust fragment" data-trim> |
|
|
|
|
let my_point = Point(x: 1.0, y: 2.0); |
|
|
|
|
</code></pre> |
|
|
|
|
... ele ainda dá uma dica de como resolver esse |
|
|
|
|
problema. |
|
|
|
|
</aside> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h3>Enums Generics</h3> |
|
|
|
|
<h2>Verificar Erros é Obrigatório</h2> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
enum Result<T, E> { |
|
|
|
|
Ok(T), |
|
|
|
@ -779,50 +608,45 @@ enum Result<T, E> {
|
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h3>Traits</h3> |
|
|
|
|
|
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
trait Summary { |
|
|
|
|
fn summarize(&self) -> String; |
|
|
|
|
match File::create("something.txt") { |
|
|
|
|
Ok(fp) => fp.write_all(b"Hello world"), |
|
|
|
|
Err(err) => println!("Failure! {}", err), |
|
|
|
|
} |
|
|
|
|
</code></pre> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h3>Traits</h3> |
|
|
|
|
|
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
struct Phrase { |
|
|
|
|
phrase: String |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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), |
|
|
|
|
} |
|
|
|
|
</code></pre> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h3>Traits</h3> |
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
let mut file = File::create("something.txt").unwrap(); |
|
|
|
|
file.write(b"Hello world").unwrap(); |
|
|
|
|
</code></pre> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
fn get_summary<T>(summarizable: T) -> String |
|
|
|
|
where T: Summary |
|
|
|
|
{ |
|
|
|
|
... |
|
|
|
|
} |
|
|
|
|
let mut file = File::create("something.txt")?; |
|
|
|
|
file.write(b"Hello world")?; |
|
|
|
|
OK(()) |
|
|
|
|
</code></pre> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h2> |
|
|
|
|
<a href="https://doc.rust-lang.org/cargo/"> |
|
|
|
|
8. Cargo |
|
|
|
|
Cargo |
|
|
|
|
</a> |
|
|
|
|
</h2> |
|
|
|
|
|
|
|
|
@ -837,7 +661,7 @@ fn get_summary<T>(summarizable: T) -> String
|
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h2>9. Tests</h2> |
|
|
|
|
<h2>Ferramenta Para Testes Já Presente</h2> |
|
|
|
|
|
|
|
|
|
<pre><code class="hljs rust" data-trim> |
|
|
|
|
#[cfg(test)] |
|
|
|
@ -864,60 +688,10 @@ test tests::testing ... ok
|
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h2>10. Macros</h2> |
|
|
|
|
|
|
|
|
|
<small class="fragment">?</small> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h3>Macros: Log-Derive</h3> |
|
|
|
|
|
|
|
|
|
<pre><code> |
|
|
|
|
#[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) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
</code></pre> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h2>11. Crazy stuff</h2> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h2>Desenvolvimento Aberto</h2> |
|
|
|
|
<img src="_images/rust-issues.png" alt="4.5k issues no Github" class="stretch"> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<a href="https://rustup.rs/">rustup</a> |
|
|
|
|
|
|
|
|
|
<div class="fragment"> |
|
|
|
|
<small>armv7-unknown-linux-gnueabihf</small> |
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
<div class="fragment"> |
|
|
|
|
<small>wasm32-unknown-unknown</small> <small class="fragment">(WebAssembly)</small> |
|
|
|
|
</div> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<img src="_images/not-everything-is-flowers.jpg" alt=""> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h3>Complicações de Rust:</h3> |
|
|
|
|
|
|
|
|
|
<ul> |
|
|
|
|
<li>Borrow checker</li> |
|
|
|
|
<li>Sem OO</li> |
|
|
|
|
<li>Tempo de compilação</li> |
|
|
|
|
</ul> |
|
|
|
|
</section> |
|
|
|
|
|
|
|
|
|
<section> |
|
|
|
|
<h2>E agora?</h2> |
|
|
|
|
|
|
|
|
|