Rust
Rust
Rust
Material Adaptado de
Marco A L Barbosa
malbarbo.pro.br
Departamento de Informática
Universidade Estadual de Maringá
cba
Este trabalho está licenciado com uma Licença Creative Commons - Atribuição-CompartilhaIgual 4.0 Internacional.
http://github.com/malbarbo/na-lp-copl
Conteúdo
Primeiros passos
O básico
2/111
Primeiros passos
Principais referências
• Página do Rust
• FAQ
• API
• StackOverflow
4/111
Olá mundo
fn main() {
println!("Olá mundo!");
}
Compilação
> rustc ola.rs
Execução
> ./arquivo
Olá mundo!
5/111
Olá mundo 2.0
use std::env;
fn main() {
if let Some(nome) = env::args().skip(1).next() {
println!("Olá {}!", nome);
} else {
println!("Olá desconhecido!");
}
}
Execução
> ./ola2
Olá desconhecido!
> ./ola2 João
Olá João!
6/111
cargo
7/111
cargo
• Criação de um projeto
> cargo new exemplo
Created binary (application) `exemplo` package
> cd exemplo
> tree
.
+-- Cargo.toml
+-- src
|-- main.rs
1 directory, 2 files
> cat src/main.rs
fn main() {
println!("Hello, world!");
}
8/111
cargo
• Compilação
9/111
cargo
10/111
Organização
11/111
Testes
12/111
Testes
#[cfg(test)]
mod tests {
use super::fat;
#[test]
fn fat_test() {
assert_eq!(1, fat(0));
assert_eq!(1, fat(1));
assert_eq!(2, fat(2));
assert_eq!(6, fat(3));
}
}
13/111
Testes
running 1 test
test tests::fat_test ... ok
14/111
Usando funções de src/lib.rs em src/main.rs
fn main() {
if let Some(n) = env::args().skip(1).next() {
if let Ok(n) = n.parse() {
println!("O fatorial de {} é {}", n, fat(n));
} else {
println!("Número inválido: {}", n);
}
} else {
println!("Forneça um número...")
}
}
15/111
Usando funções de src/lib.rs em src/main.rs
> target/debug/exemplo 10
O fatorial de 10 é 3628800
16/111
O básico
O básico
• Tipos primitivos
• Constantes e variáveis
• Estruturas de controle
• Funções
17/111
Tipos primitivos
Tipos primitivos
19/111
Tipos primitivos
• Pontos flutuante
• f32 (+/- 7 casas de precisão)
20/111
Tipos primitivos
• 10u32
• 10f32
• 10f64
21/111
Tipos primitivos
• Booleano (1 byte)
• bool (valores true e false)
• Caractere (4 bytes)
• char (valor escalar Unicode)
22/111
Operadores
• Numéricos
• +, -, *, /, %
• Relacionais
• ==, !=, >, >=, <, <=
• Lógicos
• ||, &&, !
• Bit a bit
• |, &, ^, <<, >>
• ! (inverte os bits)
23/111
Operadores
• Atribuição
• =, +=, *=, etc
24/111
Variáveis e constantes
Constantes
• Exemplos
26/111
Variáveis estáticas
• Exemplos
27/111
Variáveis
fn f(a: u32) {
let b = 10;
...
a = 10; // cannot assign to immutable argument
b = 20; // cannot assign twice to immutable variabl
}
28/111
Variáveis
fn f(mut a: u32) {
let mut x = 10;
...
a = 10;
b = 20;
}
29/111
Estruturas de controle
if
if condicao {
consequente
}
if codicao {
consequente
} else {
alternativa
}
31/111
while
while condicao {
instrucoes
}
32/111
loop
loop {
instrucoes
}
33/111
for
// versão simplificada
for var in iterator {
instrucoes
}
34/111
Funções
Máximo entre dois valores
#[test]
fn maximo_test() {
assert_eq!(-1, maximo(-1, -2));
assert_eq!(6, maximo(4, 6));
assert_eq!(5, maximo(5, 5));
}
36/111
Máximo entre dois valores
37/111
Máximo entre dois valores
38/111
Máximo entre dois valores
39/111
Posse, empréstimos e referências
Posse, empréstimos e referências
• Posse
• Empréstimos e referências
• Slices
• Referências mutáveis
40/111
Posse
O que é posse?
• Regras
• Cada valor tem uma variável que é chamada de dono
42/111
Transferência posse
43/111
Transferência posse
45/111
Transferência posse
46/111
Referências e empréstimos
Referências e empréstimos
48/111
Referências e empréstimos
• Por isso o Rust não permite que um valor seja alterado nestes
casos
50/111
Referências e empréstimos
• O código
let mut x = vec![1, 2, 3];
let y = &x[0];
x[2] = 10;
println!("y = {}", y);
• Gera o erro
3 | let y = &x[0];
| - immutable borrow occurs here
4 | x[2] = 10;
| ^ mutable borrow occurs here
5 | println!("y = {}", y);
| - immutable borrow later used her
51/111
Slices
Referências parciais
53/111
Slices
&[T]
• Note que o símbolo & ainda é usado, pois uma slice é uma
referência para um valor emprestado, isto é, que tem outro
dono
54/111
Vector e slices
56/111
Strings e slices
57/111
Strings e slices
58/111
Strings e slices
59/111
Funções que produzem referências
Funções que produzem referências
61/111
Funções que produzem referências
#[test]
fn primeiro_test() {
let valores = [6, 3, 1, 7, 1];
let mut r = primeiro(&valores, 6);
// compara os ponteiros, não os valores ; _ para que seja considerado o tipo da variável
assert_eq!(&valores[0] as *const _, r as *const _);
r = primeiro(&valores, 1);
assert_eq!(&valores[2] as *const _, r as *const _);
assert_ne!(&valores[4] as *const _, r as *const _);
}
62/111
Funções que produzem referências
63/111
Funções que produzem referências
64/111
Funções que produzem referências
65/111
Funções que produzem referências
66/111
Funções que produzem referências
67/111
Funções que produzem referências
68/111
Funções que produzem referências
O compilador também não sabe! Por isso ele diz que precisa de
mais informações
1 | pub fn primeiro(valores: &[i32], chave: &i32) -> &i32 {
| ^ expected lifetime
| parameter
|
= help: this function's return type contains a borrowed value,
but the signature does not say whether it is borrowed
from `valores` or `chave`
69/111
Funções que produzem referências
// a função não sabe (ou não precisa saber) exatamente quanto tempo valores e chave vão viver, apenas precisa
saber que existe algum escopo que pode ser substituído por 'a que irá satisfazer essa assinatura.
70/111
Funções que produzem referências
let chave = 7;
let r = {
let valores = [6, 3, 1, 7, 1];
primeiro(&valores, &chave)
};
71/111
Referências mutáveis
Referências mutáveis
let a = 5;
let x = 10;
let mut y = &x;
// ...
y = &a;
73/111
Referências mutáveis
74/111
Referências mutáveis
3 | let y = &mut x;
| ------ mutable borrow occurs here
4 | *y = 20;
5 | println!("{}", x);
| ^ immutable borrow occurs here
6 | *y = 30;
| ------- mutable borrow later used here
75/111
Referências mutáveis
76/111
Estruturas, enumerações e métodos
Estruturas
77/111
Estruturas
#[derive(Copy)]
pub struct Ponto {
x: f64,
y: f64,
}
78/111
Estruturas
#[derive(Default)]
pub struct Ponto {
x: f64,
y: f64,
}
let p = Ponto::default();
assert_eq!(0.0, p.x);
assert_eq!(0.0, p.y);
79/111
Estruturas
impl Ponto {
pub fn new(x: f64, y: f64) -> Ponto {
Ponto { x, y }
// equivalente a Ponto { x: x, y: y}
}
}
80/111
Estruturas
impl Ponto {
fn distancia_origem(&self) -> f64 {
(self.x * self.x + self.y * self.y).sqrt()
}
}
81/111
Estruturas
• Ponto::distancia_origem(&p)
82/111
Estruturas
• &self
• &mut self
83/111
Estruturas
84/111
Estruturas
85/111
Enums e casamento de padrões
Enums e casamento de padrões
enum Sinal {
Verde,
Amarelo,
Vermelho,
}
86/111
Enums e casamento de padrões
87/111
Enums e casamento de padrões
88/111
Enums e casamento de padrões
89/111
Enums e casamento de padrões
#[derive(PartialEq, Debug)]
enum Sinal {
Verde,
Amarelo,
Vermelho,
}
let sinal = Sinal::Vermelho;
// PartialEq permite usar as operações == e !=
if sinal == Sinal::Vermelho {
...
}
// Debug permite mostrar o valor usando {:?}
println!("{:?}", sinal); // printa Vermelho
// assert_eq! requer que o tipo implemente PartialEq e Debug
assert_eq!(Sinal::Verde, sinal.proximo());
90/111
Enums e casamento de padrões
91/111
Enums e casamento de padrões
enum Comando {
Listar,
Remover(usize),
Incluir {
item: String,
preco: u64,
}
}
match &comando {
Comando::Lista => ...,
Comando::Remover(x) => x ...,
Comando::Incluir { item: i, preco: p } => i, p ...,
} 92/111
Enums e casamento de padrões
match &comando {
...
Comando::Incluir { item, preco } => item, preco ...
}
93/111
Enums e casamento de padrões
match &comando {
Comando::Lista => ...,
Comando::Remover(0) => ...,
Comando::Remover(12) => ...,
Comando::Remover(x) if x > 10 => x ...,
Comando::Remover(x) => x ...,
...
}
94/111
Enums e casamento de padrões
95/111
Option
enum Option<T> {
Some(T),
None
}
96/111
Option
99/111
Option
101/111
Result
Ok(())
}
102/111
Result
103/111
Result
104/111
Outros tipos importantes
Iterator
105/111
Tipos
• Coleções
• Vec<T>
• HashMap<K, V>
106/111
Tipos
• Ponteiros inteligentes
• Box<T>
• Rc<T>
• Arc<T>
107/111
Tipos
• RefCell<T>
• UnsafeCell<T>
108/111
Traits
• Geral
• Default
• Copy
• Debug
• Display
109/111
Traits
• Operadores relacionais
• PartialEq e Eq
• PartialOrd e Ord
110/111
Traits
• Conversão
• From<T>
• Into<T>
• FromStr
111/111