# Rust (linguagem de programação)

Rust é uma linguagem de programação multiparadigma compilada desenvolvida pela Mozilla. É projetada para ser "segura, concorrente e prática", mas diferente de outras linguagens seguras, Rust não usa coletor de lixo. Possui suporte nativo ao WebAssembly.
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.
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, e está entre as 25 linguagens mais populares, de acordo com pesquisas conduzidas pela RedMonk desde 2018.

## Design

Rust se baseia nos seguintes princípios: segurança sem coletor de lixo, concorrência sem disputa de dados e abstração sem overhead. 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 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, 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.
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". 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. 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.
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; a última edição foi a 2021. Também é possível usar palavras-chave como identificadores, usando a seguinte sintaxe:

### Enumerações e casamento de padrões

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. Exemplo de declaração de enumerações e o casamento de padrões:
O comando match pode retornar valores e também pode ser usado com outros tipos. Exemplo:
Padrões irrefutáveis (que não podem falhar), como tuplas e estruturas, podem ser desestruturados de forma mais simples. Exemplo:

#### Inexistência de valor

Rust usa enumerações para representar a inexistência de um valor na forma de enum Option<T> { None, Some(T) }. Exemplo:
Existem métodos na biblioteca padrão que simplificam esse tipo de tratamento. Alguns exemplos:
Semelhante ao operador ?. em outras linguagens, também existem métodos que permitem trabalhar com o possível valor de forma segura. Alguns exemplos:

#### Tratamento de erros

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. Exemplo:
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++.
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. Exemplo de um erro personalizado:
E o tratamento do erro:
É possível simplificar o código retornando prematuramente os erros com o operador ?:

### Genéricos e lifetimes

Rust possui suporte a programação genérica e o conceito de lifetimes. 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. Todo objeto tem um dono (ownership), que pode emprestar (borrowing) ou mover (move). Ao mover a posse para outra variável, a anterior deixa de existir. Exemplo de uma árvore binária em Rust:
Rust é mais restrita que outras linguagens; dado um objeto T, é apenas possível ter um dos seguintes casos:
* 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). Outra possibilidade é o uso de alocação de arena. Exemplo de uma árvore binária usando essas estruturas:
Se houver ambiguidade na invocação de um método genérico, o tipo pode ser explicitado com o símbolo turbofish (::<>). Exemplo:
Também é possível passar valores constantes como parâmetros genéricos. Exemplo:

#### Strings e ownership

Rust possui dois tipos principais de strings: &str e String. Ambos são sempre UTF-8 válido. 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:
Se uma string possui aspas ou barra inversa, é possível usar outros delimitadores para simplificar:
Enquanto &str é estática e imutável, String é alocada dinamicamente. 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. Exemplo:
Uma função pode aceitar ambos os tipos de strings usando o traço AsRef<str>. Ou, se a conversão não for trivial mas infalível (de std::borrow::Cow, por ex), usar Into<String>. Exemplo:
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):
Em situações onde bytes ASCII são mais adequados, o tipo &[u8] pode ser usado:

### Traços e programação funcional

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. Traços podem ser deriváveis, como o Debug, onde é gerada uma implementação de forma automática usando o atributo #[derive(…)]. A implementação padrão é definida através de macros procedurais. Exemplo de traços:
Estruturas, enumerações, uniões e funções podem especificar os traços dos membros/parâmetros de forma estática (genérica):
Ou de forma dinâmica (trait objects):
Independente do tipo concreto, a instância é passada da mesma maneira:
É possível capturar lifetimes no retorno de tipos opacos com use<'_>:
A partir da edição Rust 2024 todos são capturados por padrão; para não capturar, usa-se use<>.
Por fim, traços podem ter "tipos associados" que devem ser definidos ao implementar. Exemplo:

### Iteradores e clausuras

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). No exemplo a seguir o programa lista os números primos entre 4 e 20:
Clausuras podem capturar valores do ambiente de três maneiras: emprestando imutavelmente, mutavelmente ou movendo. A última é realizada com a palavra-chave move. Exemplo:
As clausuras são representadas por três traços (e mais três equivalentes para clausuras assíncronas):
* trait FnOnce<Args> { type Output; /* ... */ } – move os valores do ambiente e pode ser chamada apenas uma vez
* trait FnMut<Args>: FnOnce<Args> { /* ... */ } – empresta valores do ambiente mutavelmente
* trait Fn<Args>: FnMut<Args> { /* ... */ } – empresta valores do ambiente imutavelmente
Exemplo:
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:
Por fim, é possível passar estruturas tuplas ou variantes de enumerações onde se espera clausuras. Exemplo:

### Unsafe

Certas atividades consideradas inseguras, como deferência de ponteiros e uso de funções unsafe, precisam estar dentro de blocos unsafe. Dentro desses blocos é responsabilidade do programador evitar comportamento indefinido. Exemplo do uso de Assembly inline:

#### Ponteiros

A criação de ponteiros não é uma atividade insegura, mas a deferência é. Exemplo retirado da documentação oficial:
Em caso de ponteiros pendentes, desalinhados ou nulos, a coerção para referências é comportamento indefinido; nesses casos, usa-se uma sintaxe alternativa:

#### Unions

Rust suporta unions para interoperabilidade com a linguagem C, e são inerentemente inseguros, podendo resultar em comportamento indefinido se usados incorretamente. Exemplo retirado da documentação oficial:

#### Interface de função externa

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:
Para expor funções para outras linguagens, deve-se desativar a decoração de nomes do Rust:

## Exemplos
### Programa Olá Mundo

Pode ser compilado e executado com o seguinte comando:

### Algoritmo de Trabb Pardo-Knuth

Rust lida com transbordamento numérico retornando f64::NAN.

### Analisador sintático

Exemplo de um analisador sintático usando um parser combinator:
E as dependências no arquivo Cargo.toml:

### Servidor HTTP

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:
E as dependências no arquivo Cargo.toml:
O log pode ser filtrado em 5 níveis de prioridade ou desativado por completo, através de uma variável de ambiente:

### Interface de linha de comandos

Exemplo de uma implementação do echo do Unix:
E as dependências no arquivo Cargo.toml:
Os argumentos podem ser passados para o executável através do Cargo usando --:

### Interface gráfica

Exemplo de uma interface gráfica usando a arquitetura Elm (Model-View-Update):
E as dependências no arquivo Cargo.toml:

### WebAssembly

Exemplo de uma interface gráfica usando a plataforma Web:
E a folha de estilos (neste exemplo é usado o framework Tailwind CSS):
E as dependências no arquivo Cargo.toml:
O alvo wasm32 precisa ser instalado para compilação cruzada, além de um bundler (Trunk):
O Trunk espera por um arquivo index.html na raiz do projeto:
E a configuração das ferramentas no arquivo Trunk.toml:
Após isso, o código pode ser compilado e servido no navegador com o seguinte comando:

## Ferramentas

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 e formatado com $ cargo fmt. A documentação de um projeto pode ser gerada a partir de comentários especiais em Markdown, usando o comando $ cargo doc. Um conjunto de lints opcionais estão disponíveis, e o código pode ser analisado usando o comando $ cargo clippy.
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:
* 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
### Renderização

* Mozilla Firefox
** Gecko – motor de renderização do Firefox
* Servo – motor de renderização experimental
* Chromium
* GNOME Loupe – o visualizador de imagens do GNOME
* librsvg – um motor de renderização de SVG; é usado pelo GNOME e pelo MediaWiki
* Ruffle – um emulador de SWF
* Alacritty – um emulador de terminal que usa OpenGL com aceleração por hardware
* Bevy – um motor de jogo orientado a dados
* Prime Video – um serviço de vídeo sob demanda; usa Rust nos apps através do WebAssembly

### Rede

* cURL – oferece o rustls (para TLS) como opção, e anteriormente ofereceu o hyper como opção de back-end HTTP, desenvolvidos em Rust
* Deno – um substituto do Node.js desenvolvido pelo criador original
* MeiliSearch – um motor de busca com interface HTTP
* Blackbird – o motor de busca especializado em código fonte do GitHub
* Discord – um serviço de chat para gamers; usa Rust no servidor e no aplicativo
* Fractal – um mensageiro baseado no protocolo Matrix
* Tor – uma rede anônima; usa Rust em alguns componentes, e uma nova versão está sendo desenvolvida em Rust do zero
* OpenDNS – um serviço de DNS
* Pingora – o novo proxy do Cloudflare, substituindo o nginx
* Cloudflare Workers – Plataforma serverless com WebAssembly
* Firecracker – virtualização para computação em nuvem desenvolvida pela Amazon, alternativa ao QEMU
* Azure IoT Edge – um serviço de inteligência para IoT; o daemon de segurança usa Rust
* npm Registry – um serviço de hospedagem de dependências para JavaScript e Node.js
* Magic Pocket – sistema de armazenamento do Dropbox
* OneSignal – um serviço de notificações push
* Figma – um editor de desenho vetorial para prototipagem de interfaces gráficas; usa Rust no servidor multiplayer

### Sistemas operacionais e componentes

* Android e Linux – suporte experimental para desenvolvimento de drivers e módulos secundários
* Google Fuchsia – usa Rust em alguns componentes
* Microsoft Windows – usa Rust em alguns componentes
* Redox – um sistema operacional tipo Unix com micronúcleo
* uutils coreutils – uma reimplementação multiplataforma dos GNU Core Utilities
* COSMIC – um ambiente de área de trabalho sendo desenvolvido pela System76 para ser usado no Pop!_OS
* GNOME – usa Rust e alguns componentes do Servo no processamento de CSS
* GStreamer – um framework multimídia; usa Rust em alguns plugins
* Stratis – um gerenciador de sistemas de arquivos usado pelo Fedora e RHEL

### Outros

* 1Password – um gerenciador de senhas
* ripgrep – um substituto moderno do grep; é usado pelo Visual Studio Code
* Tauri – um substituto do Electron
* SWC – um compilador e bundler de JavaScript e TypeScript, usado pelo Next.js, Deno, Rollup, entre outras ferramentas
* Helix – um editor de texto modal inspirado no Neovim e Kakoune
* Zed – um editor de texto inspirado no Atom, com ferramentas colaborativas
* Xi – um editor de texto usado pelo Google Fuchsia