Rust e Go são duas das linguagens de programação que mais cresceram na última década. Ambas surgiram como alternativas modernas para resolver problemas distintos, mas frequentemente aparecem lado a lado nas discussões de desenvolvedores. Em 2026, com ecossistemas maduros e comunidades vibrantes, a pergunta permanece: qual escolher para o seu próximo projeto?
Neste artigo, vamos fazer um comparativo aprofundado, analisando performance, gerenciamento de memória, modelos de concorrência, curva de aprendizado, ecossistema, mercado de trabalho e casos de uso. Vamos incluir benchmarks e exemplos de código para que você possa tomar uma decisão informada.
Visão Geral
| Aspecto | Rust | Go |
|---|---|---|
| Ano de lançamento | 2015 (1.0) | 2009 (1.0 em 2012) |
| Criador | Mozilla Research | |
| Paradigma | Multi-paradigma, sistemas | Imperativa, concorrente |
| Tipagem | Estática, forte, inferida | Estática, forte, inferida |
| Gerenciamento de memória | Ownership + Borrow Checker | Garbage Collector |
| Compilação | Nativa (LLVM) | Nativa |
| Mascote | Ferris (caranguejo) | Gopher |
Performance
Rust é consistentemente mais rápido que Go na maioria dos benchmarks. A ausência de garbage collector permite que Rust tenha latência previsível e menor consumo de memória. Go, por outro lado, oferece performance muito boa para a maioria das aplicações, especialmente considerando a simplicidade do código.
Benchmark: Ordenação de um milhão de números
Rust:
use std::time::Instant;
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
let mut numeros: Vec<i64> = (0..1_000_000)
.map(|_| rng.gen_range(0..1_000_000))
.collect();
let inicio = Instant::now();
numeros.sort_unstable();
let duracao = inicio.elapsed();
println!("Tempo de ordenação: {:?}", duracao);
println!("Primeiro elemento: {}", numeros[0]);
println!("Último elemento: {}", numeros[numeros.len() - 1]);
}
Go:
package main
import (
"fmt"
"math/rand"
"sort"
"time"
)
func main() {
numeros := make([]int64, 1_000_000)
for i := range numeros {
numeros[i] = rand.Int63n(1_000_000)
}
inicio := time.Now()
sort.Slice(numeros, func(i, j int) bool {
return numeros[i] < numeros[j]
})
duracao := time.Since(inicio)
fmt.Printf("Tempo de ordenação: %v\n", duracao)
fmt.Printf("Primeiro elemento: %d\n", numeros[0])
fmt.Printf("Último elemento: %d\n", numeros[len(numeros)-1])
}
Em benchmarks típicos, Rust completa essa tarefa em aproximadamente 45ms, enquanto Go leva cerca de 120ms. A diferença se deve à otimização agressiva do LLVM e à ausência de overhead do garbage collector em Rust.
| Métrica | Rust | Go |
|---|---|---|
| Tempo de execução | ~45ms | ~120ms |
| Uso de memória | ~8 MB | ~16 MB |
| Tamanho do binário | ~3 MB | ~2 MB |
Gerenciamento de Memória
Esta é a diferença mais fundamental entre as duas linguagens.
Rust: Ownership e Borrow Checker
Rust utiliza um sistema de ownership com regras verificadas em tempo de compilação. Isso significa zero custo em tempo de execução e garantias de segurança de memória sem garbage collector.
fn main() {
let nome = String::from("Rust Brasil");
// Transferência de ownership (move)
let outro_nome = nome;
// println!("{}", nome); // ERRO: nome foi movido
// Empréstimo (borrow) com referência
let referencia = &outro_nome;
println!("Nome: {}", referencia);
println!("Original: {}", outro_nome);
// Empréstimo mutável
let mut contador = 0;
incrementar(&mut contador);
println!("Contador: {}", contador);
}
fn incrementar(valor: &mut i32) {
*valor += 1;
}
Go: Garbage Collector
Go utiliza um garbage collector concorrente que simplifica drasticamente o desenvolvimento, mas introduz pausas (embora muito curtas em versões recentes).
package main
import "fmt"
func main() {
nome := "Rust Brasil"
// Cópias e referências são transparentes
outroNome := nome
fmt.Println(nome) // Funciona normalmente
fmt.Println(outroNome) // Cópia independente
// Ponteiros são simples
contador := 0
incrementar(&contador)
fmt.Printf("Contador: %d\n", contador)
}
func incrementar(valor *int) {
*valor++
}
Veredito: Rust oferece controle total e zero overhead, mas exige mais do programador. Go simplifica tudo com o GC, ideal para quando a latência de microsegundos não é crítica.
Modelos de Concorrência
Ambas as linguagens foram projetadas com concorrência em mente, mas com abordagens muito diferentes.
Rust: Fearless Concurrency
Rust previne data races em tempo de compilação através do sistema de tipos.
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let contador = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let contador = Arc::clone(&contador);
let handle = thread::spawn(move || {
for _ in 0..1000 {
let mut num = contador.lock().unwrap();
*num += 1;
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Resultado: {}", *contador.lock().unwrap());
// Sempre imprime 10000 - garantido pelo compilador
}
Com tokio, Rust também oferece async/await de alta performance:
use tokio;
#[tokio::main]
async fn main() {
let urls = vec![
"https://api.exemplo.com/dados1",
"https://api.exemplo.com/dados2",
"https://api.exemplo.com/dados3",
];
let mut tarefas = vec![];
for url in urls {
tarefas.push(tokio::spawn(async move {
let resp = reqwest::get(url).await.unwrap();
resp.text().await.unwrap()
}));
}
for tarefa in tarefas {
let resultado = tarefa.await.unwrap();
println!("Recebido: {} bytes", resultado.len());
}
}
Go: Goroutines e Channels
Go torna a concorrência extremamente simples com goroutines e channels.
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var contador int64
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for j := 0; j < 1000; j++ {
atomic.AddInt64(&contador, 1)
}
}()
}
wg.Wait()
fmt.Printf("Resultado: %d\n", contador)
}
O padrão de channels em Go é elegante e intuitivo:
package main
import (
"fmt"
"io"
"net/http"
)
func buscar(url string, ch chan<- string) {
resp, err := http.Get(url)
if err != nil {
ch <- fmt.Sprintf("Erro: %v", err)
return
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
ch <- fmt.Sprintf("Recebido: %d bytes", len(body))
}
func main() {
urls := []string{
"https://api.exemplo.com/dados1",
"https://api.exemplo.com/dados2",
"https://api.exemplo.com/dados3",
}
ch := make(chan string, len(urls))
for _, url := range urls {
go buscar(url, ch)
}
for range urls {
fmt.Println(<-ch)
}
}
Veredito: Go vence em simplicidade; Rust vence em segurança e performance. Goroutines são incrivelmente fáceis de usar, enquanto Rust garante ausência de data races em tempo de compilação.
Curva de Aprendizado
| Aspecto | Rust | Go |
|---|---|---|
| Tempo até produtividade | 3-6 meses | 2-4 semanas |
| Conceitos únicos | Ownership, lifetimes, traits, macros | Goroutines, interfaces implícitas |
| Mensagens de erro | Excelentes e educativas | Boas, diretas |
| Documentação | Excepcional (The Rust Book) | Muito boa (Tour of Go) |
| Complexidade do tipo | Alta (generics, traits, lifetimes) | Baixa (design minimalista) |
Go foi projetada intencionalmente para ser simples. Um programador experiente pode se tornar produtivo em Go em poucas semanas. Rust exige mais investimento inicial, mas o conhecimento adquirido se traduz em código mais robusto e performático.
Ecossistema e Ferramentas
Gerenciador de pacotes
Rust (Cargo) é amplamente considerado o melhor gerenciador de pacotes do mercado. Ele gerencia dependências, compilação, testes, documentação e publicação em uma ferramenta unificada. O registro crates.io conta com mais de 150.000 crates em 2026.
Go Modules evoluiu significativamente e é estável e confiável. O ecossistema Go é mais curado, com menos pacotes mas com a biblioteca padrão cobrindo muitos casos de uso.
| Ferramenta | Rust | Go |
|---|---|---|
| Gerenciador de pacotes | Cargo (excelente) | Go Modules (bom) |
| Formatação | rustfmt | gofmt |
| Linter | Clippy | golangci-lint |
| LSP | rust-analyzer | gopls |
| Registro de pacotes | crates.io (~150k) | pkg.go.dev |
| Testes | Integrado (cargo test) | Integrado (go test) |
Mercado de Trabalho em 2026
Ambas as linguagens apresentam excelente demanda no mercado global. Go tem uma base de vagas maior, especialmente em infraestrutura cloud e microsserviços. Rust está crescendo rapidamente, com adoção por grandes empresas como Microsoft, Google, Amazon, Meta e Linux.
| Métrica | Rust | Go |
|---|---|---|
| Salário médio (global) | $120k-160k USD/ano | $110k-150k USD/ano |
| Vagas disponíveis | Crescendo rapidamente | Estável e abundante |
| Setores principais | Sistemas, blockchain, segurança, embedded | Cloud, DevOps, backend, infra |
| Satisfação do desenvolvedor | #1 no Stack Overflow (8 anos seguidos) | Top 10 consistentemente |
No Brasil, o mercado de Go é mais estabelecido, com empresas como Mercado Livre, Nubank e iFood utilizando extensivamente. Rust está ganhando tração em fintechs e empresas de segurança, além de projetos de infraestrutura.
Casos de Uso Ideais
Quando escolher Rust
- Sistemas embarcados e IoT - controle total de memória e hardware
- Motores de jogos e renderização - performance crítica, zero overhead
- WebAssembly - Rust tem o melhor suporte WASM do mercado
- Blockchain e criptografia - segurança e performance são essenciais
- Sistemas operacionais e drivers - nível de controle comparável ao C
- CLIs de alta performance - binários pequenos e rápidos
- Quando bugs de memória são inaceitáveis - aeroespacial, automotivo, financeiro
Quando escolher Go
- Microsserviços e APIs REST - desenvolvimento rápido, deploy simples
- Ferramentas de DevOps e infraestrutura - Docker, Kubernetes, Terraform são em Go
- Serviços de rede e proxies - goroutines simplificam servidores concorrentes
- Prototipagem rápida - produtividade imediata
- Equipes grandes com rotatividade - curva de aprendizado curta
- CLIs simples - cobra + viper são muito produtivos
- Processamento de dados em streaming - channels facilitam pipelines
Exemplo Completo: Servidor HTTP
Vamos comparar a implementação de um servidor HTTP simples com endpoint JSON.
Rust (com Actix-web):
use actix_web::{web, App, HttpServer, HttpResponse};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct Mensagem {
texto: String,
timestamp: u64,
}
async fn hello() -> HttpResponse {
let msg = Mensagem {
texto: "Olá do Rust!".to_string(),
timestamp: 1708387200,
};
HttpResponse::Ok().json(msg)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
println!("Servidor rodando em http://localhost:8080");
HttpServer::new(|| {
App::new()
.route("/api/hello", web::get().to(hello))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
Go (com biblioteca padrão):
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
type Mensagem struct {
Texto string `json:"texto"`
Timestamp uint64 `json:"timestamp"`
}
func hello(w http.ResponseWriter, r *http.Request) {
msg := Mensagem{
Texto: "Olá do Go!",
Timestamp: 1708387200,
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(msg)
}
func main() {
http.HandleFunc("/api/hello", hello)
fmt.Println("Servidor rodando em http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
Note como Go consegue criar um servidor HTTP sem dependências externas, usando apenas a biblioteca padrão. Rust requer crates como actix-web e serde, mas oferece performance superior e type safety mais rigoroso.
Conclusão
Não existe uma resposta universal para “Rust ou Go”. A melhor escolha depende do seu contexto:
Escolha Rust se performance, segurança de memória e controle de baixo nível são prioridades. Esteja preparado para uma curva de aprendizado mais íngreme, mas ganhe confiança absoluta no código que você produz.
Escolha Go se produtividade, simplicidade e time-to-market são mais importantes. Go permite que equipes entreguem software confiável rapidamente, sem sacrificar demais a performance.
Em muitas organizações, a resposta é usar ambas: Go para microsserviços e tooling, Rust para componentes críticos de performance. Essa combinação aproveita o melhor de cada linguagem.
O importante é que, independentemente da sua escolha, ambas são excelentes linguagens que representam o futuro do desenvolvimento de software. Experimente as duas e descubra qual se adapta melhor ao seu estilo e às necessidades do seu projeto.
Tem experiência com Rust ou Go? Compartilhe nos comentários qual linguagem você prefere e por quê!