Rust (linguagem de programação)
Rust | |
---|---|
Paradigma | Multiparadigma: |
Surgido em | 2010 (13–14 anos) |
Última versão | 1.82.0 (17 de outubro de 2024[1]) |
Versão em teste | 1.83.0 (17 de outubro de 2024 | )
Criado por | Graydon Hoare |
Estilo de tipagem |
|
Principais implementações | |
Influenciada por | |
Influenciou | |
Plataforma |
|
Sistema operacional |
|
Licença | MIT ou Apache 2.0[10] |
Extensão do arquivo |
|
Página oficial | www |
Rust é uma linguagem de programação multiparadigma compilada desenvolvida pela Mozilla.[11] É projetada para ser "segura, concorrente e prática", mas diferente de outras linguagens seguras, Rust não usa coletor de lixo.[12][13] Possui suporte nativo ao WebAssembly.[14][15]
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.[16]
Foi considerada pelo público a linguagem "mais amada" por nove anos consecutivos, de acordo com pesquisas conduzidas pelo site Stack Overflow de 2016 a 2024,[17][18][19][20][21][22][23][24][25] e está entre as 25 linguagens mais populares, de acordo com pesquisas conduzidas pela RedMonk desde 2018.[26][27][28][29][30][31][32]
Design
[editar | editar código-fonte]Rust se baseia nos seguintes princípios: segurança sem coletor de lixo, concorrência sem disputa de dados e abstração sem overhead.[33] 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[34] e também prática para projetos de alto nível.
Através do uso de mônadas e referências, Rust consegue limitar o uso de ponteiros, reduzindo as chances de encontrar ponteiros nulos ou soltos, e dificultando falhas de segmentação. Rust gerencia memória e recursos automaticamente,[35] sem necessitar de um coletor de lixo. A linguagem impede condição de corridas 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.[36]
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".[37] 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.[38] 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.[39][40][41]
Eventualmente a sintaxe da linguagem evolui, e novas palavras-chave podem ser adicionadas. Para evitar a quebra de compatibilidade com códigos antigos, novas edições são lançadas, que projetos antigos podem ativar opcionalmente;[42] a última edição foi a 2021.[43] Também é possível usar palavras-chave como identificadores, usando a seguinte sintaxe:[44]
// `match` é uma palavra-chave
fn r#match(needle: &str, haystack: &str) -> bool {
haystack.contains(needle)
}
Enumerações e casamento de padrões
[editar | editar código-fonte]Rust possui enumerações de tipagem forte, e suas variantes podem carregar valores diversos. Casamento de padrões é muito importante em Rust, pois as enumerações são a base do tratamento de erros.[45] Exemplo de declaração de enumerações e o casamento de padrões:
enum Browser {
Firefox,
Epiphany,
Safari,
Chrome,
Edge,
Ie(u8),
}
let browser = Browser::Ie(11);
match browser {
Browser::Firefox => {
println!("Gecko");
}
Browser::Epiphany | Browser::Safari => {
println!("WebKit");
}
Browser::Ie(version) => {
println!("Internet Explorer {version}");
}
_ => println!("Chromium/Blink"), // Todos os demais
}
O comando match
pode retornar valores e também pode ser usado com outros tipos.[45] Exemplo:
let age = 27u8;
let category = match age {
// `..=4` é um padrão inclusivo (inclui 0, 1, 2, 3 e 4)
..=4 => "bebê",
5..=13 => "criança",
14..=17 => "adolescente",
18.. => "adulto",
};
println!("Com {age} ano(s) você é considerado {category}.");
Padrões irrefutáveis (que não podem falhar), como tuplas e estruturas, podem ser desestruturados de forma mais simples. Exemplo:[46]
fn print_addr(addr: (&str, &str)) {
let (protocol, domain) = addr; // Tupla desestruturada em duas variáveis
println!("Protocolo: {protocol:?}\nDomínio: {domain:?}");
}
// Forma alternativa: desestruturação de parâmetro
fn print_addr((protocol, domain): (&str, &str)) {
println!("Protocolo: {protocol:?}\nDomínio: {domain:?}");
}
Inexistência de valor
[editar | editar código-fonte]Rust usa enumerações para representar a inexistência de um valor na forma de enum Option<T> { None, Some(T) }
.[45] Exemplo:
let website = Some("https://www.wikipedia.org"); // `website: Option<&str>`
match website {
None => println!("website não especificado"),
Some(addr) => println!("website: {addr}"),
}
// Forma alternativa: if-let
if let Some(addr) = website {
// Pode usar `addr` apenas neste escopo
println!("website: {addr}");
}
// Forma alternativa: let-else
let Some(addr) = website else {
panic!("website não especificado");
// Um `return` ou `break` também é aceitável aqui
};
// Pode usar `addr` neste escopo...
Existem métodos na biblioteca padrão que simplificam esse tipo de tratamento. Alguns exemplos:[47]
let url1 = None::<&str>; // `url1: Option<&str>`
let url2 = None::<String>;
// Fornece um valor reserva
let website = url1.unwrap_or("http://www.example.com");
// Fornece o valor padrão do tipo (string vazia)
let website = url1.unwrap_or_default();
// Constrói um valor reserva através de uma clausura
let domain = "www.example.com";
let website = url2.unwrap_or_else(|| format!("http://{domain}"));
// Aborta (pânico)
let website = url1.unwrap();
// Aborta com uma explicação
let website = url1.expect("endereço inexistente");
Semelhante ao operador ?.
em outras linguagens, também existem métodos que permitem trabalhar com o possível valor de forma segura. Alguns exemplos:[47]
let website = Some("https://www.wikipedia.org");
// Transforma o valor, se houver algum
let len = website.map(|d| d.len()); // `len: Option<usize>`
// Trabalha com o valor, se houver algum. A clausura precisa retornar Option
let domain = website.and_then(|addr| addr.strip_prefix("https://")); // `domain: Option<&str>`
Tratamento de erros
[editar | editar código-fonte]Rust não possui exceções como em C++. Ao invés disso, possui duas formas de representar erros; a primeira é a macro panic!
que indica defeitos de um programa, como divisões por zero, e causam o encerramento do programa.[48] Exemplo:
for i in -5..5 {
println!("{}", 10 / i); // Pânico: divisão por zero
}
panic!("isto não deveria acontecer!"); // Alerta "pânico" manualmente
Em alguns casos óbvios de "pânico", como na divisão por zero, o compilador pode se recusar a compilar o código. 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++.[49]
A segunda forma é criando uma instância de enum Result<T, E> { Ok(T), Err(E) }
, que pode ser retornada para indicar se uma operação foi um sucesso ou não, como a leitura de um arquivo no disco.[48] Exemplo de um erro personalizado:
use std::error::Error;
use std::fmt;
// Erros podem ser de qualquer tipo
#[derive(Debug)]
#[non_exhaustive]
enum ValueError {
Empty,
TooSmall,
TooLarge,
}
// Descrição do erro
impl fmt::Display for ValueError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use ValueError::*;
match self {
Empty => "vazio",
TooSmall => "número muito pequeno",
TooLarge => "número muito grande",
}
.fmt(f)
}
}
// Métodos para extrair backtraces, entre outras coisas
impl Error for ValueError {}
// Função que pode falhar
fn verify(value: Option<i64>) -> Result<i64, ValueError> {
let Some(n) = value else {
return Err(ValueError::Empty);
};
match n {
..=3 => Err(ValueError::TooSmall),
21.. => Err(ValueError::TooLarge),
_ => Ok(n),
}
}
E o tratamento do erro:
fn main() {
let x = Some(3);
let y = Some(4);
match verify(x) {
Ok(n) => println!("Número: {n}"),
Err(err) => eprintln!("Erro: {err}"),
}
match verify(y) {
Ok(n) => println!("Número: {n}"),
Err(err) => eprintln!("Erro: {err}"),
}
}
É possível simplificar o código retornando prematuramente os erros com o operador ?
:[48]
use std::error::Error;
// `Box<dyn Error>` representa qualquer tipo que implemente `Error`
type AnyError = Box<dyn Error>;
fn main() -> Result<(), AnyError> {
let x = Some(3);
let y = Some(4);
println!("Número: {n}", n = verify(x)?);
println!("Número: {n}", n = verify(y)?); // A segunda chamada só ocorrerá se a primeira não falhar
Ok(()) // Retorna "sucesso"
}
Genéricos e lifetimes
[editar | editar código-fonte]Rust possui suporte a programação genérica e o conceito de lifetimes.[50] Todas as referências possuem um tempo de vida, que deve ser anotado no código e é verificado em tempo de compilação; em alguns casos o compilador consegue inferir e a anotação se torna opcional.[51] Todo objeto tem um dono (ownership),[52] que pode emprestar (borrowing) ou mover (move). Ao mover a posse para outra variável, a anterior deixa de existir.[53] Exemplo de uma árvore binária em Rust:
// `'a` é um lifetime, e `T` é um tipo genérico
#[derive(Debug)]
enum BinaryTree<'a, T: Copy> {
Empty,
Node {
value: T,
// Essas referências serão válidas enquanto `self` também for.
// Ou seja, é impossível criar referências circulares.
left: &'a BinaryTree<'a, T>,
right: &'a BinaryTree<'a, T>,
},
}
use BinaryTree::{Empty, Node};
let tree = Node {
value: 5.96,
left: &Empty,
right: &Node {
value: 1.0,
left: &Empty,
right: &Empty,
},
};
// Move `left`, empresta `right` e ignora `value`
if let Node {
left, ref right, ..
} = tree
{
println!("left: {left:#?},");
println!("right: {right:#?},");
}
Rust é mais restrita que outras linguagens; dado um objeto T
, é apenas possível ter um dos seguintes casos:[54]
- Ter inúmeras referências imutáveis (
&T
) para o objeto (também conhecido como aliasing) - Ter uma referência mutável
&mut T
para o objeto (também conhecido como mutabilidade)
Essa regra é aplicada pelo compilador. Em certas situações, essa regra pode não ser flexível o suficiente, como no caso de referências circulares, e para isso deve-se aplicar essa regra em tempo de execução usando algumas das várias estruturas de contagem de referências (std::rc::Rc
, std::rc::Weak
, etc) e mutabilidade interior (std::cell::Cell
, std::cell::RefCell
, std::cell::OnceCell
, etc).[55] Outra possibilidade é o uso de alocação de arena.[56] Exemplo de uma árvore binária usando essas estruturas:
use std::cell::{Cell, RefCell};
use std::rc::{Rc, Weak};
// Apelido para simplificar
type WeakRef<T> = Weak<RefCell<T>>;
#[derive(Debug)]
struct BinaryTree<T: Copy> {
value: Cell<T>,
left: WeakRef<BinaryTree<T>>, // `left: Weak<RefCell<BinaryTree<T>>>`
right: WeakRef<BinaryTree<T>>,
}
let tree = Rc::new(RefCell::new(BinaryTree {
value: Cell::new(5.96),
left: Weak::new(), // Referência inválida, por enquanto
right: Weak::new(),
}));
{
// Empresta mutavelmente. Se já houver um empréstimo, causa pânico
let left = &mut tree.borrow_mut().left;
// Aponta a subárvore esquerda para a raiz da árvore, criando uma
// referência circular. `Rc::clone()` apenas incrementa o contador
// de referências, e `Rc::downgrade()` transforma `Rc` em `Weak`.
*left = Rc::downgrade(&Rc::clone(&tree));
} // Devolve `left` no fim do escopo
let left_fmt = tree
.borrow()
.left
.upgrade() // Verifica se é uma referência válida…
.map(|node| format!("{:#?}", node.borrow()))
.unwrap_or_else(|| "Empty".into()); // …Ou não
println!("left: {left_fmt},");
Se houver ambiguidade na invocação de um método genérico, o tipo pode ser explicitado com o símbolo turbofish (::<>
).[57] Exemplo:
let dollar = "5.96"
.parse::<f64>()
.expect("falha ao converter para `f64`");
println!("US$ 1.00 = R$ {dollar}");
Também é possível passar valores constantes como parâmetros genéricos. Exemplo:[58]
struct Array<T, const N: usize> {
data: [T; N],
}
let arr = Array { data: [0u64; 5] }; // `arr: Array<u64, 5>`
Strings e ownership
[editar | editar código-fonte]Rust possui dois tipos principais de strings: &str
e String
. Ambos são sempre UTF-8 válido.[59] Existe um tempo de vida especial chamado 'static
, que indica que a referência é válida até o fim da execução do programa. Todas os literais de strings possuem ele implicitamente:[51]
let hello: &str = "Olá, Mundo!"; // Implicitamente estática
let hello: &'static str = "Olá, Mundo!"; // O mesmo que acima
Se uma string possui aspas ou barra inversa, é possível usar outros delimitadores para simplificar:[57]
let json = r#"{ "message": "Olá, Mundo!\n" }"#; // Exemplo de JSON
let json = "{ \"message\": \"Olá, Mundo!\\n\" }"; // O mesmo que acima
Enquanto &str
é estática e imutável, String
é alocada dinamicamente.[60] Uma função pode usar a enumeração std::borrow::Cow
(copy-on-write) para retornar &str
ou String
(ou &[T]
ou Vec<T>
, etc) conforme a necessidade de mutação/ownership.[61] Exemplo:
use std::borrow::Cow;
// A anotação do lifetime aqui pode ser omitida
fn trim<'a>(input: &'a str) -> Cow<'a, str> {
// `str::trim()` retorna um slice (referência) sem os espaços em branco
let trimmed = input.trim();
// Se o slice for diferente do original, significa que
// existe espaços em branco no original.
if trimmed != input {
// Retorna uma nova String sem os espaços em branco
return trimmed.to_owned().into(); // `Cow::Owned(String)`
}
// Retorna a string original sem modificação
input.into() // `Cow::Borrowed(&str)`
}
Uma função pode aceitar ambos os tipos de strings usando o traço AsRef<str>
.[62] Ou, se a conversão não for trivial mas infalível (de std::borrow::Cow
, por ex), usar Into<String>
.[63] Exemplo:
// use std::borrow::Cow;
fn trim<T>(input: T) -> String
where
T: AsRef<str>,
// T: Into<String>,
{
// Retorna uma nova String incondicionalmente
input.as_ref().trim().to_string()
// input.into().trim().to_string()
}
let trimmed_from_str = trim("Olá, Mundo!");
let trimmed_from_string = trim("Olá, Mundo!".to_string());
// let trimmed_from_cow = trim(Cow::from("Olá, Mundo!"));
Além de &str
e String
, Rust possui vários outros tipos de strings especializados, como &std::ffi::CStr
e std::ffi::CString
(para compatibilidade com a linguagem C):[64]
use std::ffi::CStr;
let hello: &CStr = c"Olá, Mundo!"; // Terminado com NUL (b'\x00')
Em situações onde bytes ASCII são mais adequados, o tipo &[u8]
pode ser usado:[57]
let hello: &[u8] = b"Ol\xC3\xA1, Mundo!"; // 'á' não é um caractere válido em ASCII
let hello: &[u8] = &[79, 108, 195, 161, 44, 32, 77, 117, 110, 100, 111, 33]; // O mesmo que acima
let hello = String::from_utf8_lossy(hello); // Constrói uma string dos bytes
Traços e programação funcional
[editar | editar código-fonte]Rust possui suporte a traços (traits) que definem o comportamento de um objeto, e podem ser implementados por estruturas, enumerações, uniões e tipos básicos.[65][66] Traços podem ser deriváveis, como o Debug
, onde é gerada uma implementação de forma automática usando o atributo #[derive(…)]
.[67] A implementação padrão é definida através de macros procedurais.[68] Exemplo de traços:
trait Animal {
// Método estático que retorna uma string estática
fn common_name() -> &'static str;
}
trait Bird: Animal {
// Traços podem fornecer definições padrões para métodos
// `&self` é uma referência a instância
fn fly(&self) {
println!("Voou para longe.");
}
}
trait Talk {
fn talk(&self); // O mesmo que `fn talk(&self) -> ();`
}
#[derive(Debug)] // Implementa `Debug`
struct Duck<'a> {
name: &'a str,
}
// Implementa `Animal`.
// A anotação do lifetime aqui foi elidida, mas poderia ser declarada. Ex.:
// impl<'a> Animal for Duck<'a> { /* ... */ }
impl Animal for Duck<'_> {
fn common_name() -> &'static str {
"Pato"
}
}
// Implementa `Bird` com as definições padrões
impl Bird for Duck<'_> {}
// Implementa `Talk`
impl Talk for Duck<'_> {
fn talk(&self) {
println!("Quack!");
}
}
let common_name = Duck::common_name(); // Método estático
let duck = Duck { name: "Deka" }; // Nova instância
duck.fly(); // O mesmo que `Bird::fly(&duck);`
duck.talk(); // O mesmo que `Talk::talk(&duck);`
Estruturas, enumerações, uniões e funções podem especificar os traços dos membros/parâmetros de forma estática (genérica):[65]
fn do_talk<T>(animal: &T)
where
T: Bird + Talk,
{
animal.talk();
}
// Ou o equivalente:
fn do_talk<T: Bird + Talk>(animal: &T) {
animal.talk();
}
// Ou com um tipo anônimo (incompatível com o turbofish):
fn do_talk(animal: &(impl Bird + Talk)) {
animal.talk();
}
Ou de forma dinâmica (trait objects):[66]
// Apenas uma trait base pode ser usada, com exceção de auto traits.
// Use `Box<dyn Talk>` para alocação dinâmica.
fn do_talk_dyn(animal: &dyn Talk) {
animal.talk();
}
Independente do tipo concreto, a instância é passada da mesma maneira:[65][66]
let duck = Duck { name: "Deka" };
let dog = Dog { name: "Duke" }; // Uma outra estrutura que implementa os mesmos traços
do_talk(&duck);
do_talk(&dog);
do_talk_dyn(&duck);
do_talk_dyn(&dog);
É possível capturar lifetimes no retorno de tipos opacos com use<'_>
:[69]
// Captura o lifetime de `arg`.
// A anotação do lifetime aqui foi elidida, mas poderia ser declarada. Ex.:
// fn str_to_iter<'a>(arg: &'a str) -> impl Iterator<Item = char> + use<'a> { /* ... */ }
fn str_to_iter(arg: &str) -> impl Iterator<Item = char> + use<'_> {
arg.chars()
}
Por fim, traços podem ter "tipos associados" que devem ser definidos ao implementar.[70] Exemplo:
trait Iterator {
type Item;
/* ... */
}
impl Iterator for Bytes<'_> {
type Item = u8;
/* ... */
}
fn analyze(iter: &mut impl Iterator<Item = u8>) {
/* ... */
}
Iteradores e clausuras
[editar | editar código-fonte]Em Rust, todos os iteradores implementam trait Iterator { type Item; /* ... */ }
, que fornece métodos adaptadores para consumir ou criar novos iteradores. Também possui um literal para representar intervalos (um tipo de iterador).[71] No exemplo a seguir o programa lista os números primos entre 4 e 20:
let mut numbers = vec![];
// `4..=20` é um iterador inclusivo (inclui 20)
for i in 4..=20 {
// `2..i` é um iterador exclusivo, ex.: `2..5` inclui 2, 3 e 4.
// `|x| i % x != 0` é uma clausura que recebe `x` e retorna booliano.
if (2..i).all(|x| i % x != 0) {
numbers.push(i);
}
}
println!("Os números primos entre 4 e 20 são: {numbers:?}");
Clausuras podem capturar valores do ambiente de três maneiras: emprestando imutavelmente, mutavelmente ou movendo. A última é realizada com a palavra-chave move
.[72] Exemplo:
use std::thread;
let msg = "Olá, Mundo!".to_owned();
thread::spawn(move || {
println!("{msg}"); // `msg` movido aqui
});
As clausuras são representadas por três traços:[72]
trait Fn<Args> { type Output; /* ... */ }
– empresta valores do ambiente imutavelmentetrait FnMut<Args>: Fn<Args> { /* ... */ }
– empresta valores do ambiente mutavelmentetrait FnOnce<Args>: FnMut<Args> { /* ... */ }
– move os valores do ambiente e pode ser chamada apenas uma vez
Exemplo:
fn convert<F>(num: f64, handler: F) -> f64
where
F: FnOnce(f64) -> f64, // Assinatura da clausura
{
handler(num)
}
fn main() {
let y = convert(499.0, |num| num * 5.96);
println!("{y}");
}
Clausuras são anônimas e não têm um tipo concreto previamente conhecido, mesmo que possuam a mesma assinatura; por esse motivo, para retornar uma clausura de uma função, é necessário usar uma sintaxe especial:[65]
fn convert() -> impl FnOnce(f64) -> f64 {
move |num| num * 5.96
}
fn main() {
let f = convert();
println!("{y}", y = f(499.99));
}
Por fim, é possível passar estruturas tuplas ou variantes de enumerações onde se espera clausuras. Exemplo:
let seq: Box<_> = (1..=5).map(Some).collect();
println!("{seq:?}"); // [Some(1), Some(2), Some(3), Some(4), Some(5)]
Unsafe
[editar | editar código-fonte]Certas atividades consideradas inseguras, como deferência de ponteiros e uso de funções unsafe
, precisam estar dentro de blocos unsafe
.[73] Dentro desses blocos é responsabilidade do programador evitar comportamento indefinido.[74] Exemplo do uso de Assembly inline:[75]
use std::arch::asm;
// Multiplica `x` por 6 usando shifts e adds
let mut x: u64 = 4;
unsafe {
asm!(
"mov {tmp}, {x}",
"shl {tmp}, 1",
"shl {x}, 2",
"add {x}, {tmp}",
x = inout(reg) x,
tmp = out(reg) _,
);
}
assert_eq!(x, 4 * 6);
Ponteiros
[editar | editar código-fonte]A criação de ponteiros não é uma atividade insegura, mas a deferência é. Exemplo retirado da documentação oficial:[73]
let mut num = 5;
let r1 = &num as *const i32; // Ponteiro constante para `num` (coerção)
let r2 = &mut num as *mut i32; // Ponteiro mutável para `num` (coerção)
unsafe {
println!("r1 is: {}", *r1); // Deferência
println!("r2 is: {}", *r2); // Deferência
}
Em caso de ponteiros pendentes, desalinhados ou nulos, a coerção para referências é comportamento indefinido; nesses casos, usa-se uma sintaxe alternativa:[76]
#[repr(packed)] // Altera o alinhamento da estrutura
struct Packed {
not_aligned_field: i32,
}
let p = Packed {
not_aligned_field: 1_82,
};
let ptr = &raw const p.not_aligned_field; // Ponteiro desalinhado (sem coerção)
let val = unsafe { ptr.read_unaligned() }; // Acesso ao ponteiro
Unions
[editar | editar código-fonte]Rust suporta unions para interoperabilidade com a linguagem C, e são inerentemente inseguros,[73] podendo resultar em comportamento indefinido se usados incorretamente.[77] Exemplo retirado da documentação oficial:[77]
#[repr(C)]
union MyUnion {
f1: u32,
f2: f32,
}
let u = MyUnion { f1: 1 };
let f = unsafe { u.f1 }; // Leitura de campo
Interface de função externa
[editar | editar código-fonte]Rust pode usar funções e estáticos de código externo (da linguagem C, por exemplo). Eles são declarados em blocos unsafe extern
:[78]
// ABI da linguagem C
unsafe extern "C" {
pub safe static TAU: f64;
pub safe fn sqrt(x: f64) -> f64;
pub unsafe fn strlen(p: *const u8) -> usize;
}
// ABI da Win32 API
unsafe extern "stdcall" {
/* ... */
}
Para expor funções para outras linguagens, deve-se desativar a decoração de nomes do Rust:[73]
#[unsafe(no_mangle)]
pub extern "C" fn call_from_c() {
/* ... */
}
Exemplos
[editar | editar código-fonte]Programa Olá Mundo
[editar | editar código-fonte]fn main() {
println!("Olá, Mundo!");
}
Pode ser compilado e executado com o seguinte comando:[79]
$ cargo run
Algoritmo de Trabb Pardo-Knuth
[editar | editar código-fonte]use std::{io, iter::zip};
fn f(t: f64) -> Option<f64> {
let y = t.abs().sqrt() + 5.0 * t.powi(3);
(y <= 400.0).then_some(y)
}
fn main() {
let mut a = [0f64; 11];
for (t, input) in zip(&mut a, io::stdin().lines()) {
*t = input.unwrap().parse().unwrap();
}
a.iter().enumerate().rev().for_each(|(i, &t)| match f(t) {
None => println!("{i} TOO LARGE"),
Some(y) => println!("{i} {y}"),
});
}
Rust lida com transbordamento numérico retornando f64::NAN
.
Analisador sintático
[editar | editar código-fonte]Exemplo de um analisador sintático usando um parser combinator:
use nom::bytes::complete::{tag, take_while_m_n};
use nom::{combinator::map_res, sequence::tuple, IResult};
#[derive(Debug)]
pub struct Color {
pub red: u8,
pub green: u8,
pub blue: u8,
}
fn hex_primary(input: &str) -> IResult<&str, u8> {
map_res(
take_while_m_n(2, 2, |c: char| c.is_ascii_hexdigit()),
|input| u8::from_str_radix(input, 16),
)(input)
}
fn hex_color(input: &str) -> IResult<&str, Color> {
let (input, _) = tag("#")(input)?;
let (input, (red, green, blue)) = tuple((hex_primary, hex_primary, hex_primary))(input)?;
Ok((input, Color { red, green, blue }))
}
fn main() {
let (_, color) = hex_color("#2F14DF").expect("sintaxe inválida");
println!("#2F14DF => {color:?}");
}
E as dependências no arquivo Cargo.toml
:
[dependencies]
nom = "7.1"
Servidor HTTP
[editar | editar código-fonte]Exemplo de um web service RESTful (HTTP) usando funções assíncronas e serialização para JSON; responde com um número de CPF formatado, se for válido, ao acessar http://localhost:3000/consultar-cpf/123
:
use axum::{extract::Path, response::Redirect, routing::get, Json, Router};
use serde::Serialize;
use time::{serde::rfc3339, OffsetDateTime};
#[derive(Serialize)]
struct CheckCpfResponse {
valid: bool,
formatted: Option<brids::Cpf>,
#[serde(with = "rfc3339")]
timestamp: OffsetDateTime,
}
async fn check_cpf(Path(numbers): Path<String>) -> Json<CheckCpfResponse> {
let result = numbers.parse();
Json(CheckCpfResponse {
valid: result.is_ok(),
formatted: result.ok(),
timestamp: OffsetDateTime::now_utc(),
})
}
#[tokio::main]
async fn main() {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
format!(
"{}=debug,tower_http=debug,axum::rejection=trace",
env!("CARGO_CRATE_NAME")
)
.into()
}),
)
.init();
let app = Router::new()
.route("/", get(|| async { Redirect::to("/consultar-cpf/123") }))
.route("/consultar-cpf/:numbers", get(check_cpf))
.layer(tower_http::trace::TraceLayer::new_for_http().on_request(()));
let listener = tokio::net::TcpListener::bind(("127.0.0.1", 3000))
.await
.unwrap();
tracing::debug!("listening on http://{}", listener.local_addr().unwrap());
axum::serve(listener, app).await.unwrap();
}
E as dependências no arquivo Cargo.toml
:
[dependencies]
tracing = "0.1.40"
[dependencies.axum]
version = "0.7.7"
features = ["tracing"]
[dependencies.brids]
version = "0.5.1"
features = ["serde"]
[dependencies.serde]
version = "1.0"
features = ["derive"]
[dependencies.time]
version = "0.3.36"
features = ["serde-well-known"]
[dependencies.tokio]
version = "1.40"
features = ["full"]
[dependencies.tower-http]
version = "0.6.1"
features = ["trace"]
[dependencies.tracing-subscriber]
version = "0.3.18"
features = ["env-filter"]
O log pode ser filtrado em 5 níveis de prioridade ou desativado por completo, através de uma variável de ambiente:[80]
$ RUST_LOG=trace cargo run
Interface de linha de comandos
[editar | editar código-fonte]Exemplo de uma implementação do echo do Unix:
use clap::Parser;
/// Ecoa o(s) TEXTO(s) para a saída padrão.
#[derive(Parser, Debug)]
#[command(version, about)]
struct Args {
/// Não emitir o caractere de nova linha do final.
#[arg(short = 'n')]
strip_trailing_newline: bool,
#[arg(value_name = "TEXTO")]
strings: Vec<String>,
}
fn main() {
let args = Args::parse();
let output = args.strings.join(" ");
print!("{output}");
if !args.strip_trailing_newline {
println!();
}
}
E as dependências no arquivo Cargo.toml
:
[dependencies.clap]
version = "4.5"
features = ["derive"]
Os argumentos podem ser passados para o executável através do Cargo usando --
:[81]
$ cargo run -- --help
$ cargo run -- "Olá, Mundo!"
Interface gráfica
[editar | editar código-fonte]Exemplo de uma interface gráfica usando a arquitetura Elm (Model-View-Update):
use std::num::Saturating;
use iced::widget::{button, center, column, text};
use iced::{Center, Element, Task};
struct Counter(Saturating<u8>);
#[derive(Debug, Clone)]
enum Message {
Decrement,
}
fn update(Counter(ref mut count): &mut Counter, message: Message) {
match message {
Message::Decrement => *count -= 1,
}
}
fn view(Counter(count): &Counter) -> Element<Message> {
let enabled = count.0 > 0;
let content = column![
match count.0 {
0 => text!("Fim."),
1 => text!("Encerra no próximo clique!"),
n => text!("Encerra em {n} cliques."),
}
.size(18),
button("Contar").on_press_maybe(enabled.then_some(Message::Decrement)),
]
.align_x(Center)
.spacing(8);
center(content).into()
}
fn main() -> iced::Result {
env_logger::init_from_env(env_logger::Env::default().default_filter_or("warn"));
let data = Counter(Saturating(5));
iced::application("Contador", update, view).run_with(|| (data, Task::none()))
}
E as dependências no arquivo Cargo.toml
:
[dependencies]
env_logger = "0.11.5"
iced = "0.13.1"
log = "0.4.22"
WebAssembly
[editar | editar código-fonte]Exemplo de uma interface gráfica usando a plataforma Web:
use std::num::Saturating;
use leptos::prelude::*;
#[component]
fn Counter(#[prop(default = 5)] start: u8) -> impl IntoView {
let (count, set_count) = signal(Saturating(start));
let disabled = move || count.read().0 == 0;
let decrement = move |_| *set_count.write() -= 1;
view! {
<div class="flex flex-col items-center justify-center gap-2 h-screen">
<span class="font-sans text-lg">
{move || match count.read().0 {
0 => view! { "Fim." }.into_any(),
1 => view! { "Encerra no próximo clique!" }.into_any(),
n => view! { "Encerra em " {n} " cliques." }.into_any(),
}}
</span>
<button disabled={disabled} on:click={decrement}>"Contar"</button>
</div>
}
}
fn main() {
_ = console_log::init_with_level(log::Level::Debug);
console_error_panic_hook::set_once();
mount_to_body(|| view! { <Counter start=5 /> });
}
E a folha de estilos (neste exemplo é usado o framework Tailwind CSS):
@tailwind base;
@tailwind components;
@tailwind utilities;
E as dependências no arquivo Cargo.toml
:
[dependencies]
console_error_panic_hook = "0.1.7"
console_log = "1"
log = "0.4.22"
[dependencies.leptos]
version = "0.7.0-rc0"
features = ["csr"]
O alvo wasm32 precisa ser instalado para compilação cruzada, além de um bundler (Trunk):
$ rustup target add wasm32-unknown-unknown
$ cargo install --locked trunk
O Trunk espera por um arquivo index.html
na raiz do projeto:
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link data-trunk rel="tailwind-css" href="/assets/css/index.css" />
<title>Contador</title>
</head>
<body></body>
</html>
E a configuração do Tailwind CSS para processar os arquivos:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["*.html", "./src/**/*.rs"],
theme: {
extend: {},
},
plugins: [],
corePlugins: {
preflight: false,
},
}
Após isso, o código pode ser compilado e servido no navegador com o seguinte comando:
$ trunk serve --open
Ferramentas
[editar | editar código-fonte]Cargo é a ferramenta de produtividade oficial, e usa arquivos TOML para listar dependências e configurações de um projeto. Um projeto pode ser testado usando o comando $ cargo test
[82][83] e formatado com $ cargo fmt
.[84] A documentação de um projeto pode ser gerada a partir de comentários especiais em Markdown, usando o comando $ cargo doc
.[83][85] Um conjunto de lints opcionais estão disponíveis, e o código pode ser analisado usando o comando $ cargo clippy
.[84]
Rust possui uma implementação do Language Server Protocol, o rust-analyzer, que fornece autocompletar, formatação e refatoração independente do editor de texto ou ambiente de desenvolvimento integrado. Os seguintes editores dão suporte ao rust-analyzer de forma nativa ou através de extensões/plugins:[84][86]
- Visual Studio Code – fornecido pela extensão oficial
- Helix – suporte nativo
- Zed – suporte nativo
- Kate – suporte nativo
- GNOME Builder – suporte nativo
- Microsoft Visual Studio – fornecido por uma extensão
Outras ferramentas dão suporte a Rust através de implementações próprias sem o uso do rust-analyzer:
- RustRover – versão do IntelliJ IDEA para Rust
- Vim – fornecido pelo plugin oficial rust.vim
- Emacs – fornecido pelo plugin oficial rust-mode
- Sublime Text – fornecido pelo pacote oficial Rust Enhanced
- Eclipse – fornecido pelo plugin Corrosion
Software desenvolvido em Rust
[editar | editar código-fonte]- Renderização
- Mozilla Firefox[87]
- Servo – motor de renderização experimental
- Chromium[89]
- GNOME Loupe – o visualizador de imagens do GNOME[90]
- librsvg – um motor de renderização de SVG;[91][92] é usado pelo GNOME e pelo MediaWiki[93]
- Ruffle – um emulador de SWF[94]
- Prime Video – um serviço de vídeo sob demanda; usa Rust nos apps através do WebAssembly[95]
- Rede
- cURL – oferece o hyper como opção de back-end HTTP, desenvolvido em Rust[96]
- Deno – um substituto do Node.js desenvolvido pelo criador original[97][98]
- MeiliSearch – um motor de busca com interface HTTP[99]
- Blackbird – o motor de busca especializado em código fonte do GitHub[100]
- Discord – um serviço de chat para gamers; usa Rust no servidor e no aplicativo[101]
- Fractal – um mensageiro baseado no protocolo Matrix[102]
- Tor – uma rede anônima; usa Rust em alguns componentes,[103] e uma nova versão está sendo desenvolvida em Rust do zero[104]
- OpenDNS – um serviço de DNS[105][106][107]
- Pingora – o novo proxy do Cloudflare, substituindo o nginx[108]
- Cloudflare Workers – Plataforma serverless com WebAssembly[109]
- Firecracker – virtualização para computação em nuvem desenvolvida pela Amazon, alternativa ao QEMU[110]
- Azure IoT Edge – um serviço de inteligência para IoT; o daemon de segurança usa Rust[111]
- npm Registry – um serviço de hospedagem de dependências para JavaScript e Node.js[112]
- Magic Pocket – sistema de armazenamento do Dropbox[113][114]
- OneSignal – um serviço de notificações push[115][116]
- Figma – um editor de desenho vetorial para prototipagem de interfaces gráficas; usa Rust no servidor multiplayer[117]
- Sistemas operacionais e componentes
- Android e Linux – suporte experimental para desenvolvimento de drivers e módulos secundários[118][119][120][121][122]
- Google Fuchsia – usa Rust em alguns componentes[123]
- Microsoft Windows – usa Rust em alguns componentes[124]
- Redox – um sistema operacional tipo Unix com micronúcleo[125]
- uutils coreutils – uma reimplementação multiplataforma dos GNU Core Utilities[126]
- COSMIC – um ambiente de área de trabalho sendo desenvolvido pela System76 para ser usado no Pop!_OS[127]
- GNOME – usa Rust e alguns componentes do Servo no processamento de CSS[128]
- GStreamer – um framework multimídia; usa Rust em alguns plugins[129][130]
- Stratis – um gerenciador de sistemas de arquivos usado pelo Fedora e RHEL[131]
- Outros
- 1Password – um gerenciador de senhas[132][133]
- ripgrep – um substituto moderno do grep; é usado pelo Visual Studio Code[134]
- Tauri – um substituto do Electron[135]
- SWC – um compilador e bundler de JavaScript e TypeScript, usado pelo Next.js,[136] Deno, Rollup, entre outras ferramentas[137]
- Helix – um editor de texto modal inspirado no Neovim e Kakoune[138]
- Zed – um editor de texto inspirado no Atom, com ferramentas colaborativas[139]
- Xi – um editor de texto usado pelo Google Fuchsia[140][141]
Ver também
[editar | editar código-fonte]Referências
- ↑ «Announcing Rust 1.82.0». blog.rust-lang.org (em inglês). 17 de outubro de 2024. Consultado em 17 de outubro de 2024
- ↑ «What is rustc?». doc.rust-lang.org (em inglês). Consultado em 16 de outubro de 2021
- ↑ «WIP libgccjit codegen backend for rust». github.com (em inglês). Consultado em 16 de outubro de 2021
- ↑ «GCC Front-End For Rust». rust-gcc.github.io (em inglês). Consultado em 16 de outubro de 2021
- ↑ «Appendix: Influences - The Rust Reference» (em inglês). The Rust Project Developers. Consultado em 29 de novembro de 2020
- ↑ Tovilo, Ilija (22 de maio de 2020). «PHP RFC: Match expression v2». wiki.php.net. Consultado em 29 de novembro de 2020
- ↑ «Features of Rhai - Rhai - Embedded Scripting for Rust». rhai.rs. Consultado em 9 de abril de 2023
- ↑ Kelley, Andrew (24 de janeiro de 2018). «Unsafe Zig is Safer Than Unsafe Rust». andrewkelley.me. Consultado em 11 de fevereiro de 2020
- ↑ a b c d «Rust Platform Support». doc.rust-lang.org (em inglês). Consultado em 18 de outubro de 2024
- ↑ «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
- ↑ «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. 15 de maio de 2015. Consultado em 12 de outubro de 2015
- ↑ «Stack Overflow Developer Survey 2016 Results». Stack Overflow. 14 de junho de 2016. Consultado em 11 de dezembro de 2017
- ↑ «Stack Overflow Developer Survey 2017». Stack Overflow. 7 de junho de 2017. Consultado em 11 de dezembro de 2017
- ↑ «Stack Overflow Developer Survey 2018». Stack Overflow. 15 de maio de 2018. Consultado em 16 de abril de 2018
- ↑ «Stack Overflow Developer Survey 2019». Stack Overflow. 18 de abril de 2019. Consultado em 9 de julho de 2019
- ↑ «Stack Overflow Developer Survey 2020». Stack Overflow. 22 de junho de 2020. Consultado em 21 de julho de 2020
- ↑ «Stack Overflow Developer Survey 2021». Stack Overflow. 2 de agosto de 2021. Consultado em 22 de agosto de 2021
- ↑ «Stack Overflow Developer Survey 2022». Stack Overflow. 22 de junho de 2022. Consultado em 27 de junho de 2022
- ↑ «Stack Overflow Developer Survey 2023». Stack Overflow. 13 de junho de 2023. Consultado em 20 de julho de 2023
- ↑ «Technology | 2024 Stack Overflow Developer Survey». Stack Overflow. 24 de junho de 2024. Consultado em 19 de agosto de 2024
- ↑ 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
- ↑ O'Grady, Stephen (28 de fevereiro de 2020). «The RedMonk Programming Language Rankings: January 2020» (em inglês). RedMonk. Consultado em 21 de julho de 2020
- ↑ O'Grady, Stephen (1 de março de 2021). «The RedMonk Programming Language Rankings: January 2021» (em inglês). RedMonk. Consultado em 7 de março de 2021
- ↑ O'Grady, Stephen (28 de março de 2022). «The RedMonk Programming Language Rankings: January 2022» (em inglês). RedMonk. Consultado em 27 de junho de 2022
- ↑ O'Grady, Stephen (16 de maio de 2023). «The RedMonk Programming Language Rankings: January 2023» (em inglês). RedMonk. Consultado em 20 de julho de 2023
- ↑ O'Grady, Stephen (8 de março de 2024). «The RedMonk Programming Language Rankings: January 2024» (em inglês). RedMonk. Consultado em 27 de maio de 2024
- ↑ «Rust in 2016 - The Rust Programming Language Blog». blog.rust-lang.org. 14 de agosto de 2015. 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. 10 de abril de 2015. Consultado em 12 de outubro de 2015
- ↑ Stroustrup, Bjarne (2012). «Foundations of C++ - ETAPS 2012 Keynote» (PDF). Consultado em 19 de agosto de 2024
- ↑ «Abstraction without overhead: traits in Rust - The Rust Programming Language Blog». blog.rust-lang.org. 11 de maio de 2015. 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
- ↑ «Appendix E: Editions - The Rust Programming Language» (em inglês). Consultado em 19 de outubro de 2020
- ↑ «Rust 2021 - The Edition Guide» (em inglês). Consultado em 21 de outubro de 2021
- ↑ «Appendix A: Keywords - The Rust Programming Language» (em inglês). Consultado em 19 de outubro de 2020
- ↑ 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
- ↑ «Refutability: Whether a Pattern Might Fail to Match - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 14 de março de 2023
- ↑ a b «Option in std::option - Rust». doc.rust-lang.org (em inglês). Consultado em 7 de abril de 2021
- ↑ a b c «Error Handling - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 2 de dezembro de 2017
- ↑ «catch_unwind in std::panic» (em inglês). The Rust Project Developers. Consultado em 15 de fevereiro de 2018
- ↑ «Generic Types, Traits, and Lifetimes - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 28 de julho de 2020
- ↑ a b «Validating References with Lifetimes - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 23 de janeiro de 2021
- ↑ «What is Ownership? - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 28 de julho de 2020
- ↑ «References and Borrowing - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 30 de agosto de 2020
- ↑ «std::cell - Rust». doc.rust-lang.org (em inglês). Consultado em 24 de maio de 2024
- ↑ «RefCell<T> and the Interior Mutability Pattern - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 30 de agosto de 2020
- ↑ «Graphs and arena allocation | Rust for C++ Programmers» (em inglês). Consultado em 30 de agosto de 2020
- ↑ a b c «Appendix B: Operators and Symbols - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 31 de dezembro de 2020
- ↑ «Const generics MVP hits beta!». blog.rust-lang.org (em inglês). 26 de fevereiro de 2021. Consultado em 26 de março de 2021
- ↑ «str - Rust». doc.rust-lang.org (em inglês). Consultado em 18 de março de 2022
- ↑ «String in std::string - Rust». doc.rust-lang.org (em inglês). Consultado em 18 de março de 2022
- ↑ «Cow in std::borrow - Rust». doc.rust-lang.org (em inglês). Consultado em 19 de março de 2022
- ↑ «AsRef in std::convert - Rust». doc.rust-lang.org (em inglês). Consultado em 25 de maio de 2024
- ↑ «Into in std::convert - Rust». doc.rust-lang.org (em inglês). Consultado em 26 de maio de 2024
- ↑ «CStr in std::ffi - Rust». doc.rust-lang.org (em inglês). Consultado em 18 de março de 2023
- ↑ a b c d «Traits: Defining Shared Behavior - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 30 de dezembro de 2020
- ↑ a b c «Using Trait Objects That Allow for Values of Different Types - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 30 de dezembro de 2020
- ↑ «Appendix C: Derivable Traits - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 23 de janeiro de 2021
- ↑ «Appendix D: Macros - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 23 de janeiro de 2021
- ↑ «Announcing Rust 1.82.0 § Precise capturing use<..> syntax». blog.rust-lang.org (em inglês). 17 de outubro de 2024. Consultado em 18 de outubro de 2024
- ↑ «Advanced Traits - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 27 de maio de 2022
- ↑ «Iterators - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 5 de dezembro de 2017
- ↑ a b «Closures - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 5 de dezembro de 2017
- ↑ a b c d «Unsafe Rust - The Rust Programming Language» (em inglês). The Rust Project Developers. Consultado em 24 de fevereiro de 2022
- ↑ «Behavior considered undefined - The Rust Reference» (em inglês). The Rust Project Developers. Consultado em 2 de junho de 2022
- ↑ «Announcing Rust 1.59.0 § Inline assembly». blog.rust-lang.org (em inglês). 24 de fevereiro de 2022. Consultado em 24 de fevereiro de 2022
- ↑ «Announcing Rust 1.82.0 § Native syntax for creating a raw pointer». blog.rust-lang.org (em inglês). 17 de outubro de 2024. Consultado em 17 de outubro de 2024
- ↑ a b «Unions - The Rust Reference» (em inglês). The Rust Project Developers. Consultado em 18 de março de 2022
- ↑ «External blocks - The Rust Reference» (em inglês). The Rust Project Developers. Consultado em 18 de outubro de 2024
- ↑ «Hello, World! - The Rust Programming Language, Second Edition» (em inglês). The Rust Project Developers. Consultado em 6 de setembro de 2017
- ↑ «EnvFilter in tracing_subscriber::filter - Rust». docs.rs (em inglês). Consultado em 12 de outubro de 2024
- ↑ «cargo run - The Cargo Book». doc.rust-lang.org (em inglês). Consultado em 7 de junho de 2024
- ↑ «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
- ↑ a b c «Tools - Rust Programming Language». www.rust-lang.org (em inglês). Consultado em 2 de junho de 2022
- ↑ «Documentation - The Rust Programming Language» (em inglês). 1 de outubro de 2016. Consultado em 26 de setembro de 2017
- ↑ «Rust Analyzer - User Manual». rust-analyzer.github.io (em inglês). Consultado em 27 de março de 2024
- ↑ Herman, Dave (12 de julho de 2016). «Shipping Rust in Firefox» (em inglês). Mozilla. Consultado em 9 de agosto de 2020
- ↑ Bryant, David (27 de outubro de 2016). «A Quantum Leap for the Web» (em inglês). Mozilla. Consultado em 1 de outubro de 2024
- ↑ Jansens, Dana (12 de janeiro de 2023). «Supporting the Use of Rust in the Chromium Project» (em inglês). Google. Consultado em 14 de dezembro de 2023
- ↑ Rudra, Sourav (12 de maio de 2023). «Loupe is the New Image Viewer App for GNOME». news.itsfoss.com (em inglês). Consultado em 1 de junho de 2024
- ↑ Mena Quintero, Federico (3 de janeiro de 2017). «Librsvg 2.41.0 is released». mail.gnome.org (em inglês). Consultado em 9 de agosto de 2020
- ↑ Mena Quintero, Federico (9 de agosto de 2017). «Replacing C library code with Rust: What I learned with librsvg» (PDF). people.gnome.org (em inglês). Consultado em 9 de agosto de 2020
- ↑ «Image administration - MediaWiki». www.mediawiki.org (em inglês). Consultado em 9 de agosto de 2020
- ↑ «Flash is dead—but South Africa didn't get the memo» (em inglês). Ars Technica. 2 de fevereiro de 2021. Consultado em 4 de maio de 2024
- ↑ Ene, Alexandru (27 de janeiro 2022). «How Prime Video updates its app for more than 8,000 device types». The switch to WebAssembly increases stability, speed. (em inglês). Amazon. Consultado em 27 de outubro de 2022
- ↑ McArthur, Sean (28 de junho de 2021). «How using hyper in curl can help make the internet safer» (em inglês). Amazon Web Services. Consultado em 18 de março de 2022
- ↑ Dahl, Ryan; Belder, Bert; Iwańczuk, Bartek (12 de maio de 2020). «Deno 1.0» (em inglês). Consultado em 9 de agosto de 2020
- ↑ Krill, Paul (14 de maio 2020). «Deno 1.0 arrives to challenge Node.js». ‘Secure by default’ runtime for JavaScript and Typescript runtime reaches important milestone (em inglês). InfoWorld. Consultado em 1 de junho de 2024
- ↑ Dreimanis, Gints (13 de abril de 2021). «Rust in Production: MeiliSearch». serokell.io (em inglês). Consultado em 27 de outubro de 2022
- ↑ Clem, Timothy (6 de fevereiro de 2023). «The technology behind GitHub's new code search». A look at what went into building the world's largest public code search index. (em inglês). GitHub. Consultado em 11 de fevereiro de 2023
- ↑ Howarth, Jesse (4 de fevereiro de 2020). «Why Discord is switching from Go to Rust» (em inglês). Discord. Consultado em 9 de agosto de 2020
- ↑ «World / fractal - GitLab». gitlab.gnome.org (em inglês). Consultado em 27 de março de 2021
- ↑ «The Wilmington Watch: A Tor Network Team Hackfest» (em inglês). blog.torproject.org. 5 de julho de 2017. Consultado em 9 de agosto de 2020
- ↑ «Arti 0.1.0 is released: Your somewhat-stable API is here!» (em inglês). blog.torproject.org. 1 de março de 2022. Consultado em 18 de março de 2022
- ↑ Balbaert, Ivo (27 de maio de 2015). Rust Essentials (em inglês). [S.l.]: Packt Publishing. p. 6. 184 páginas. ISBN 978-1-7852-8576-9. Consultado em 9 de agosto de 2020
- ↑ Frank, Denis (5 de dezembro de 2013). «Using HyperLogLog to Detect Malware Faster Than Ever». OpenDNS Security Labs. Consultado em 9 de agosto de 2020
- ↑ Denis, Frank (4 de outubro de 2013). «ZeroMQ: Helping us Block Malicious Domains in Real Time». OpenDNS Security Labs. Consultado em 9 de agosto de 2020
- ↑ Wu, Yuchen; Hauck, Andrew (14 de setembro de 2022). «How we built Pingora, the proxy that connects Cloudflare to the Internet» (em inglês). Cloudflare. Consultado em 22 de setembro de 2022
- ↑ Pack, Steven (16 de outubro de 2018). «Serverless Rust with Cloudflare Workers» (em inglês). Cloudflare. Consultado em 9 de agosto de 2020
- ↑ Cimpanu, Catalin (15 de outubro de 2019). «AWS to sponsor Rust project». ZDNET (em inglês). Consultado em 17 de julho de 2024
- ↑ Nichols, Shaun (27 de junho de 2018). «Serverless Rust with Cloudflare Workers» (em inglês). The Register. Consultado em 27 de março de 2021
- ↑ «Community makes Rust an easy choice for npm» (PDF) (em inglês). The Rust Project Developers. 25 de fevereiro de 2019. Consultado em 9 de agosto de 2020
- ↑ Gupta, Akhil (14 de março 2016). «Scaling to exabytes and beyond» (em inglês). Dropbox. Consultado em 9 de agosto de 2020
- ↑ Metz, Cade (14 de março 2016). «The Epic Story of Dropbox's Exodus From the Amazon Cloud Empire» (em inglês). Wired. Consultado em 9 de agosto de 2020
- ↑ Wilm, Joe (21 de março 2016). «OneSignal now sends iOS push notifications 100x faster». onesignal.com (em inglês). Consultado em 28 de maio de 2022
- ↑ Wilm, Joe (4 de janeiro 2017). «Rust at OneSignal». onesignal.com (em inglês). Consultado em 28 de maio de 2022
- ↑ Wallace, Evan (2 de maio 2018). «Rust in Production at Figma». How Mozilla’s Rust dramatically improved our server-side performance (em inglês). Figma. Consultado em 19 de maio de 2022
- ↑ Vander Stoep, Jeff; Hines, Stephen (6 de abril de 2021). «Rust in the Android platform» (em inglês). Google. Consultado em 22 de abril de 2021
- ↑ Vander Stoep, Jeff (1 de dezembro de 2022). «Memory Safe Languages in Android 13» (em inglês). Google. Consultado em 14 de dezembro de 2023
- ↑ Almeida Filho, Wedson (14 de abril de 2021). «Rust in the Linux kernel» (em inglês). Google. Consultado em 22 de abril de 2021
- ↑ Ojeda, Miguel (14 de abril de 2021). «[PATCH 00/13] [RFC] Rust support» (em inglês). LKML. Consultado em 22 de abril de 2021
- ↑ Vaughan-Nichols, Steven (19 de setembro de 2022). «Linus Torvalds: Rust will go into Linux 6.1» (em inglês). ZDNet. Consultado em 22 de setembro de 2022
- ↑ «Language usage in Fuchsia». fuchsia.dev (em inglês). Consultado em 27 de março de 2021
- ↑ «Using Rust in Windows - Microsoft Security Response Center» (em inglês). Microsoft. 7 de novembro 2019. Consultado em 9 de agosto de 2020
- ↑ Yegulalp, Serdar (21 de março de 2016). «Rust's Redox OS could show Linux a few new tricks» (em inglês). InfoWorld. Consultado em 9 de agosto de 2020
- ↑ Isaiah, Ayooluwa (8 de junho de 2021). «Rewriting the GNU Coreutils in Rust». LWN.net (em inglês). Consultado em 8 de junho de 2024
- ↑ Patel, Pratham (14 de janeiro 2022). «I Tried System76's New Rust-based COSMIC Desktop!». news.itsfoss.com (em inglês). Consultado em 4 de maio de 2024
- ↑ Mena Quintero, Federico (21 de novembro 2019). «Remove libcroco». gitlab.gnome.org (em inglês). Consultado em 27 de março de 2021
- ↑ «gst-plugins-rs - Various GStreamer plugins written in Rust». gitlab.freedesktop.org (em inglês). Consultado em 27 de março de 2021
- ↑ «Writing GStreamer plugins and elements in Rust». coaxion.net (em inglês). 17 de maio de 2016. Consultado em 27 de março de 2021
- ↑ «Fedora 29 new features: Startis now officially in Fedora». www.marksei.com (em inglês). 10 de outubro de 2018. Consultado em 9 de agosto de 2020
- ↑ Brown, Sarah (4 de dezembro de 2019). «1Password X 1.17: New brain, new menu, and even more accessible». blog.1password.com (em inglês). Consultado em 29 de setembro de 2021
- ↑ Dreimanis, Gints (20 de janeiro de 2021). «Rust in Production: 1Password». serokell.io (em inglês). Consultado em 29 de setembro de 2021
- ↑ «Visual Studio Code March 2017 (version 1.11) - Text search improvements». code.visualstudio.com (em inglês). Março de 2017. Consultado em 9 de agosto de 2020
- ↑ Tyson, Matthew (23 de março 2023). «Intro to Tauri: The Electron alternative». Build cross-platform native applications using virtually any web framework and a Rust back end. Here's a look at Tauri under the hood. (em inglês). InfoWorld. Consultado em 1 de junho de 2024
- ↑ Davis, Connor; Kang, DongYoon; Monaco, Gerald; Velasco, Javi; Liu, Jiachi; Kasper, JJ; Erickson, Kara; Teegarden, Maia; Ding, Shu; "styfle", Steven; Neutkens, Tim; Koppers, Tobias (26 de outubro de 2021). «Next.js 12». nextjs.org (em inglês). Consultado em 22 de dezembro de 2023
- ↑ «Rust-based platform for the Web – SWC». swc.rs (em inglês). Consultado em 22 de dezembro de 2023
- ↑ «Helix» (em inglês). Consultado em 28 de março de 2024
- ↑ Eastman, David (8 de abril de 2023). «Zed: A New Multiplayer Code Editor from the Creators of Atom». Zed is a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter. David Eastman takes the beta for a spin. (em inglês). Consultado em 19 de agosto de 2024
- ↑ Levien, Raph (23 de janeiro de 2018). «Xi: an editor for the next 20 years» (em inglês). Consultado em 9 de agosto de 2020
- ↑ «A modern editor with a backend written in Rust» (em inglês). Google. Consultado em 9 de agosto de 2020
Bibliografia
[editar | editar código-fonte]- Klabnik, Steve; Nichols, Carol (6 agosto de 2019) [julho de 2018]. The Rust Programming Language. Covers Rust 2018 (em inglês) 2 ed. [S.l.]: No Starch Press. 526 páginas. ISBN 978-1-7185-0044-0
- Balbaert, Ivo (7 de novembro de 2017) [27 de maio de 2015]. Rust Essentials. A Quick Guide to Writing Fast, Safe, and Concurrent Systems and Applications (em inglês) 2 ed. [S.l.]: Packt Publishing. 264 páginas. ISBN 978-1-7883-9913-5
- Bos, Mara (janeiro de 2023). Rust Atomics and Locks. Low-Level Concurrency in Practice (em inglês). [S.l.]: O'Reilly Media, Inc. 250 páginas. ISBN 978-1-0981-1944-7
Ligações externas
[editar | editar código-fonte]- Sítio oficial
- Rust no GitHub
- «The Rust Programming Language» (em inglês). Livro oficial
- «Rust Playground» (em inglês). Experimente Rust online