Rust (linguagem de programação)
Rust | |
---|---|
![]() | |
Paradigma | orientada a objetos, estruturada, imperativa compilada, concorrente, funcional |
Surgido em | 2010 (8–9 anos) |
Última versão | 1.39.0 (7 de novembro de 2019[1]) |
Criado por | Graydon Hoare, Rust Project Developers, Mozilla |
Estilo de tipagem: | Estática, forte, inferida |
Compiladores | rustc |
Influenciada por | Alef, C#, C++, Cyclone, Erlang, Haskell, Hermes, Limbo, Newsqueak, NIL, OCaml, Ruby, Scheme, Standard ML, Swift[2] |
Influenciou | Crystal, Dyon, Swift, Idris |
Plataforma | Prioridade 1: i686 e x86-64[3] Prioridade 2: ARM e AArch64, PowerPC e PPC64, i386, i586, MIPS e MIPS64, SPARC, S390x, asm.js, WebAssembly[3] |
Sistema operacional | Linux, Windows, macOS, FreeBSD, NetBSD, Android, iOS, Fuchsia, Solaris, Redox[3] |
Licença: | MIT ou Apache 2.0[4] |
Extensão do arquivo: | .rs, .rlib |
Página oficial | www |
Rust é uma linguagem de programação multiparadigma compilada desenvolvida pela Mozilla Research.[5] É projetada para ser "segura, concorrente e prática",[6][7] suportando os estilos puramente funcional, procedural, e orientado a objetos. Possui suporte nativo ao WebAssembly.[8][9]
A linguagem apareceu como um projeto pessoal de Graydon Hoare, empregado da Mozilla. A organização começou a apoiar o projeto em 2009 e anunciou-o em 2010. No mesmo ano, os esforços mudaram do compilador original (escrito em OCaml) para um auto-hospedado feito em Rust. Conhecido por rustc, conseguiu compilar-se pela primeira vez em 2011 e utiliza o LLVM como back-end. Foi lançada pela primeira vez uma versão numerada pré-alfa em 2012. Rust 1.0, a primeira versão estável, foi lançada em 15 de Maio de 2015.[10]
Foi considerada pelo público a linguagem "mais amada" por quatro anos consecutivos, de acordo com uma pesquisa conduzida pelo site Stack Overflow em 2016,[11] 2017,[12] 2018[13] e 2019,[14] e está entre as 25 linguagens mais populares, de acordo com uma pesquisa conduzida pela RedMonk.[15][16]
DesignEditar
Rust se baseia nos seguintes princípios: segurança sem coletor de lixo, concorrência sem disputa de dados e abstração sem overhead.[17] Estes princípios fazem com que Rust seja rápida para ser usada em aplicações de baixo nível como o motor de renderização Servo[18] e também prática para projetos de alto nível.
Em Rust não existem ponteiros nulos ou ponteiros soltos, impossibilitando falhas de segmentação. Rust gerencia memória e recursos automaticamente,[19] sem necessitar de um coletor de lixo. A linguagem impede corridas de dados entre threads pois não é possível que duas threads possam modificar um mesmo valor ao mesmo tempo. Para que uma referência possa ser compartilhada entre várias threads, ela deve ser somente leitura. Existem diversas técnicas seguras de comunicação entre threads.[20]
O princípio de abstração sem overhead vem do C++. Nas palavras de Bjarne Stroustrup: "Você não paga por aquilo que você não usa. E mais: aquilo que você usa, não conseguiria programar melhor à mão".[21] Rust permite um alto grau de abstração através do sistema de traits, que são interfaces que podem ser implementadas separadamente da declaração de um tipo.[22] Tipos genéricos são utilizados extensamente.
O projeto Rust usa o conceito de "canais de lançamento", semelhante ao Mozilla Firefox; são 3 canais: Nightly, Beta e Stable ("estável"). Diariamente é lançada uma nova versão Nightly, e a cada seis semanas a última versão desse canal é promovida para Beta, e só receberá atualizações para corrigir falhas sérias. Simultaneamente, a última versão Beta é promovida para Stable.[23][24][25]
Iteradores e clausurasEditar
Rust possui um literal para representar iteradores, e traz em sua biblioteca padrão métodos para transformá-los, usando clausuras.[26][27] No exemplo a seguir o programa lista os 10 primeiros números primos:
fn main() {
const LIMIT: usize = 10;
let mut numbers = Vec::with_capacity(LIMIT); // Vetor vazio pré-alocado
let mut i = 2; // Números menores que 2 não são primos
// Repete até conseguir 10 números
while numbers.len() < LIMIT {
// Verifica se i é divisível apenas por ele mesmo e 1.
// 2..i é um iterador exclusivo, ex.: 2..5 inclui 2, 3 e 4.
// |x| i % x != 0 é uma clausura, que recebe um inteiro (x) e retorna um booleano.
if (2..i).all(|x| i % x != 0) {
numbers.push(i);
}
i += 1;
}
println!("Os {} primeiros números primos são: {:?}", LIMIT, numbers);
// Cria um iterador para o vetor, filtra os valores e gera um novo vetor.
// Transformações podem ser combinadas em uma única iteração em collect().
// O underscore (_) abaixo sinaliza para o compilador tentar inferir o tipo.
let slice: Vec<_> = numbers.into_iter().filter(|&x| x > 10 && x < 20).collect();
println!("Entre 10 e 20 encontram-se: {:?}", slice);
}
Enumerações e casamento de padrõesEditar
Rust possui enumerações de tipagem forte, que podem carregar valores diversos. Casamento de padrões é muito importante em Rust, pois as enumerações são a base do tratamento de erros.[28] Exemplo de declaração de enumerações e o casamento de padrões:
enum Color {
Red(u8), // Variantes podem carregar valores
Yellow(u8),
Blue(u8),
Orange,
Purple,
Green,
}
fn main() {
let color = Color::Red(25);
match color {
Color::Red(a) | Color::Yellow(a) | Color::Blue(a) => {
println!("Cor primária. Alpha: {}%", a);
}
Color::Orange => println!("Laranja."),
_ => println!("Demais cores."), // Demais cores
}
}
O comando match
também pode ser usado com outros tipos.[28] Exemplo:
fn main() {
let age: u8 = 27; // u8 é um inteiro sem sinal de 8 bits
// match pode retornar valores também
let category = match age {
// 0..=4 é um padrão inclusivo (inclui 0, 1, 2, 3 e 4)
0..=4 => "bebê",
5..=13 => "criança",
14..=17 => "adolescente",
_ => "adulto",
}; // ponto-e-vírgula obrigatório quando usa retorno
println!("Com {} ano(s) você é considerado {}.", age, category);
}
Rust usa enumerações para representar a inexistência de um valor na forma de enum Option<T> { None, Some(T) }
.[28] Exemplo:
fn main() {
let website = Some("http://www.example.com"); // website: Option<&str>
match website {
None => println!("Website não especificado."),
Some(addr) => println!("Website: {}", addr),
}
// Formas alternativas ao match
let num: Option<i8> = None; // i8 é um inteiro de 8 bits
if num.is_none() {
println!("Número não especificado.");
}
if let Some(n) = num {
println!("Número: {}", n);
}
}
Tratamento de errosEditar
Rust não possui exceções como em C++. Ao invés disso, possui duas representações de erros: recuperáveis e irrecuperáveis. Os erros recuperáveis são os esperados no fluxo normal de um programa, e são comunicados através do retorno de funções na forma de enum Result<T, E> { Ok(T), Err(E) }
.[29] Exemplo:
use std::fs::File;
use std::io::Read; // Trait necessária para usar o método read_to_string()
fn main() {
match File::open("exemplo.txt") {
Ok(mut file) => { // Se o arquivo existir
let mut txt = String::new();
file.read_to_string(&mut txt).ok(); // ok() ignora o Result desta chamada
println!("{}", txt);
}
Err(err) => println!("Erro: {}", err), // Se o arquivo não existir
}
}
Os erros irrecuperáveis são usados para sinalizar problemas na lógica de um programa, como divisões por zero, e causam o encerramento do programa.[29] Exemplo:
fn main() {
let num = 10 / 0; // "Pânico"
panic!("Isto não deveria acontecer!"); // Alerta "pânico" manualmente
}
Rust permite recuperar de alguns "pânicos" com a função especial std::panic::catch_unwind()
, que não deve ser usada para emular o tratamento de exceções de C++.[30]
ExemplosEditar
Programa Olá MundoEditar
fn main() {
println!("Olá, Mundo!");
}
Pode ser compilado e executado com o seguinte comando:[31]
$ cargo run
Algoritmo de Trabb Pardo-KnuthEditar
fn f(t: f64) -> f64 {
t.abs().sqrt() + 5.0 * t.powi(3)
}
fn main() {
let mut a = [0f64; 11];
for t in &mut a {
let mut num = String::new();
std::io::stdin().read_line(&mut num).ok();
*t = num.trim().parse().unwrap();
}
for t in a.iter().rev() {
let y = f(*t);
if y > 400.0 || y.is_nan() {
println!("Valor muito grande");
} else {
println!("{}", y);
}
}
}
Rust lida com transbordamento numérico retornando NAN
.
FerramentasEditar
Cargo é a ferramenta de produtividade oficial, e usa arquivos TOML para listar dependências e configurações de um projeto.[32][33] A documentação de um projeto pode ser gerada a partir de comentários especiais em Markdown, usando o comando $ cargo doc
.[33][34]
Rust possui uma implementação do Language Server Protocol, o RLS, que fornece autocompletar e refatoração independente do editor de texto ou ambiente de desenvolvimento integrado. Os seguintes editores dão suporte ao RLS de forma nativa ou através de extensões/plugins:[35][36]
- Visual Studio Code - fornecido pela extensão oficial
- Sublime Text - fornecido pelo pacote oficial Rust Enhanced
- Atom - fornecido pelo pacote oficial ide-rust
- Visual Studio - fornecido por uma extensão
- Eclipse - fornecido pelo plugin Corrosion
- GNOME Builder - suporte nativo
Outras ferramentas dão suporte a Rust através de implementações próprias sem o uso do RLS:
- IntelliJ IDEA - fornecido pelo plugin IntelliJ Rust
- Vim - fornecido pelo plugin oficial rust.vim
- Emacs - fornecido pelo plugin oficial rust-mode
Ver tambémEditar
Referências
- ↑ «Announcing Rust 1.39.0». blog.rust-lang.org (em inglês). 7 de novembro de 2019. Consultado em 7 de novembro de 2019
- ↑ «Appendix: Influences - The Rust Reference» (em inglês). The Rust Project Developers. Consultado em 7 de dezembro de 2017
- ↑ a b c «Rust Platform Support». forge.rust-lang.org (em inglês). Consultado em 15 de fevereiro de 2018
- ↑ «rust/COPYRIGHT at master · rust-lang/rust». github.com. Consultado em 21 de julho de 2018
- ↑ «The Rust Language». Lambda the Ultimate. 8 de julho de 2010. Consultado em 30 de outubro de 2010
- ↑ «The Rust Programming Language». Consultado em 21 de outubro de 2012
- ↑ «Doc language FAQ». Consultado em 21 de outubro de 2012
- ↑ Rediger, Jan-Erik (26 de novembro de 2017). «wasm32-unknown-unknown landed & enabled». www.hellorust.com. Consultado em 11 de dezembro de 2017
- ↑ Gattozzi, Michael (5 de dezembro de 2017). «Rust and the case for WebAssembly in 2018». mgattozzi.com. Consultado em 11 de dezembro de 2017
- ↑ «Announcing Rust 1.0 - The Rust Programming Language Blog». blog.rust-lang.org. Consultado em 12 de outubro de 2015
- ↑ «Stack Overflow Developer Survey 2016 Results». Stack Overflow. Consultado em 11 de dezembro de 2017
- ↑ «Stack Overflow Developer Survey 2017». Stack Overflow. Consultado em 11 de dezembro de 2017
- ↑ «Stack Overflow Developer Survey 2018». Stack Overflow. Consultado em 16 de abril de 2018
- ↑ «Stack Overflow Developer Survey 2019». Stack Overflow. Consultado em 9 de julho de 2019
- ↑ O'Grady, Stephen (7 de março de 2018). «The RedMonk Programming Language Rankings: January 2018» (em inglês). RedMonk. Consultado em 13 de março de 2018
- ↑ O'Grady, Stephen (20 de março de 2019). «The RedMonk Programming Language Rankings: January 2019» (em inglês). RedMonk. Consultado em 9 de julho de 2019
- ↑ «Rust in 2016 - The Rust Programming Language Blog». blog.rust-lang.org. Consultado em 12 de outubro de 2015
- ↑ «servo/servo». GitHub. Consultado em 12 de outubro de 2015
- ↑ «Rust Means Never Having to Close a Socket». Inside Skylight. Consultado em 12 de outubro de 2015
- ↑ «Fearless Concurrency with Rust - The Rust Programming Language Blog». blog.rust-lang.org. Consultado em 12 de outubro de 2015
- ↑ http://www.stroustrup.com/ETAPS-corrected-draft.pdf
- ↑ «Abstraction without overhead: traits in Rust - The Rust Programming Language Blog». blog.rust-lang.org. Consultado em 12 de outubro de 2015
- ↑ Aaron Turon (12 de dezembro de 2014). «Rust 1.0: Scheduling the trains» (em inglês). The Rust Project Developers. Consultado em 6 de setembro de 2017
- ↑ «Release Channels - The Rust Programming Language» (em inglês). The Rust Project Developers. Consultado em 6 de setembro de 2017
- ↑ «Releases · rust-lang/rust». github.com. Consultado em 15 de fevereiro de 2018
- ↑ «Iterators - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 5 de dezembro de 2017
- ↑ «Closures - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 5 de dezembro de 2017
- ↑ a b c «Enums and Pattern Matching - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 2 de dezembro de 2017
- ↑ a b «Error Handling - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 2 de dezembro de 2017
- ↑ «Function std::panic::catch_unwind» (em inglês). The Rust Project Developers. Consultado em 15 de fevereiro de 2018
- ↑ «Hello, World! - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 6 de setembro de 2017
- ↑ «Cargo Guide» (em inglês). Consultado em 26 de setembro de 2017
- ↑ a b «The Manifest Format» (em inglês). Consultado em 26 de setembro de 2017
- ↑ «Documentation - The Rust Programming Language» (em inglês). 1 de outubro de 2016. Consultado em 26 de setembro de 2017
- ↑ «Rust and IDEs». forge.rust-lang.org (em inglês). Consultado em 29 de março de 2018
- ↑ «Are we (I)DE yet?». areweideyet.com (em inglês). Consultado em 29 de março de 2018
Ligações externasEditar
- Sítio oficial
- Rust no GitHub
- The Rust Programming Language (em inglês) - livro oficial
- Rust Playground (em inglês) - experimente Rust online