---
title: "Transição para Rust: Guia por Linguagem de Origem"
url: "https://rustlang.com.br/carreira/transicao-para-rust/"
markdown_url: "https://rustlang.com.br/carreira/transicao-para-rust.MD"
description: "Guia completo de transição para Rust para desenvolvedores vindos de C++, Java, Python, Go e JavaScript. Mapeamento de conceitos, mudanças de mentalidade e armadilhas comuns por linguagem."
date: ""
author: ""
---

# Transição para Rust: Guia por Linguagem de Origem

Guia completo de transição para Rust para desenvolvedores vindos de C++, Java, Python, Go e JavaScript. Mapeamento de conceitos, mudanças de mentalidade e armadilhas comuns por linguagem.


# Transição para Rust: Guia por Linguagem de Origem

Migrar para Rust é uma decisão estratégica cada vez mais comum entre desenvolvedores experientes. Porém, independentemente da sua linguagem de origem, Rust exige mudanças significativas na forma como você pensa sobre código. Este guia oferece caminhos personalizados para desenvolvedores vindos de C++, Java, Python, Go e JavaScript, mapeando conceitos familiares para seus equivalentes em Rust e destacando as armadilhas específicas de cada transição.

O objetivo não é apenas ensinar a sintaxe, mas ajudá-lo a internalizar o modelo mental do Rust --- o que vai tornar seu código mais seguro, mais performático e mais prazeroso de escrever.

---

## Mudanças Universais de Mentalidade

Independentemente da sua linguagem de origem, estes conceitos são fundamentais para pensar em Rust.

### Ownership: cada valor tem um dono

Em Rust, cada valor na memória tem exatamente um dono (owner). Quando o dono sai do escopo, o valor é liberado automaticamente. Não há garbage collector nem gerenciamento manual de memória.

```rust
fn main() {
    let nome = String::from("Rust Brasil"); // nome é dono da String
    let outro = nome;                       // ownership movido para outro
    // println!("{}", nome);                // ERRO! nome não é mais válido
    println!("{}", outro);                  // OK
}
```

### Borrowing: empréstimo de referências

Em vez de mover valores, você pode emprestá-los via referências. Existem duas regras:

1. Você pode ter **várias referências imutáveis** OU **uma referência mutável**, nunca ambas ao mesmo tempo
2. Referências devem sempre ser válidas (não podem apontar para dados liberados)

```rust
fn main() {
    let mut dados = vec![1, 2, 3];

    // Múltiplas referências imutáveis: OK
    let ref1 = &dados;
    let ref2 = &dados;
    println!("{:?} {:?}", ref1, ref2);

    // Referência mutável: OK (refs imutáveis já saíram de uso)
    let ref_mut = &mut dados;
    ref_mut.push(4);

    println!("{:?}", dados);
}
```

### Lifetimes: garantindo validade de referências

Lifetimes são anotações que dizem ao compilador por quanto tempo uma referência é válida. Na maioria dos casos, o compilador infere sozinho (elision), mas às vezes você precisa ser explícito.

```rust
// O compilador precisa saber que a referência retornada
// vive pelo menos tanto quanto ambos os parâmetros
fn mais_longo<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}
```

### Sem null: Option e Result

Rust não tem `null`. Em vez disso, usa tipos algébricos:

```rust
// Option<T> para valores que podem não existir
fn buscar_usuario(id: u64) -> Option<String> {
    if id == 1 {
        Some(String::from("Maria"))
    } else {
        None
    }
}

// Result<T, E> para operações que podem falhar
fn dividir(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err(String::from("Divisão por zero"))
    } else {
        Ok(a / b)
    }
}
```

---

## Transição de C++ para Rust

### Semelhanças que facilitam

Se você vem de C++, muitos conceitos serão familiares:

| C++ | Rust | Notas |
|-----|------|-------|
| `std::unique_ptr<T>` | `Box<T>` | Ownership exclusivo no heap |
| `std::shared_ptr<T>` | `Arc<T>` / `Rc<T>` | Ownership compartilhado |
| `std::move()` | Move semântico padrão | Em Rust, move é o padrão |
| `const T&` | `&T` | Referência imutável |
| `T&` | `&mut T` | Referência mutável |
| Templates | Generics + Traits | Monomorfização similar |
| RAII | RAII (Drop trait) | Muito similar |
| `std::optional<T>` | `Option<T>` | Idêntico em conceito |
| `std::variant` | `enum` | Enums em Rust são mais poderosos |
| Namespaces | Modules | Sistema de módulos mais estruturado |

### O que muda

**1. Sem herança de implementação**

Em Rust, não existe herança de classes. Use composição e traits.

```rust
// C++ (herança)
// class Animal { virtual void falar(); };
// class Cachorro : public Animal { void falar() override; };

// Rust (composição + traits)
trait Animal {
    fn falar(&self) -> String;
    fn nome(&self) -> &str;
}

struct Cachorro {
    nome: String,
}

impl Animal for Cachorro {
    fn falar(&self) -> String {
        format!("{} diz: Au au!", self.nome)
    }

    fn nome(&self) -> &str {
        &self.nome
    }
}

// Dispatch dinâmico quando necessário
fn fazer_falar(animal: &dyn Animal) {
    println!("{}", animal.falar());
}
```

**2. Borrow checker vs. gerenciamento manual**

Você não precisa mais se preocupar com:
- Use-after-free
- Double-free
- Dangling pointers
- Data races

O compilador garante tudo em tempo de compilação.

```rust
// Isto NÃO compila (e é isso que queremos!)
fn perigoso() -> &String {
    let local = String::from("oi");
    &local // ERRO: local será liberado ao fim da função
}

// Solução: retornar o valor por ownership
fn seguro() -> String {
    let local = String::from("oi");
    local // Move a ownership para o chamador
}
```

**3. Macros procedurais vs. macros de texto**

As macros de Rust são higiênicas e operam na AST, não em texto.

```rust
// Macro declarativa simples
macro_rules! vec_de_strings {
    ($($x:expr),*) => {
        vec![$($x.to_string()),*]
    };
}

fn main() {
    let nomes = vec_de_strings!["Alice", "Bob", "Carol"];
    println!("{:?}", nomes);
}
```

### Armadilhas comuns para programadores C++

1. **Tentar usar ponteiros brutos**: em Rust, use referências (`&T`, `&mut T`) e smart pointers (`Box`, `Rc`, `Arc`)
2. **Querer herança**: use composição e traits em vez de hierarquias de classes
3. **Esquecer que move é o padrão**: em C++ você precisa de `std::move`, em Rust todo assignment é um move (exceto para tipos `Copy`)
4. **Sobrecarregar operadores indiscriminadamente**: em Rust, implement traits como `Add`, `Mul`, `Index` com parcimônia
5. **Usar `unsafe` cedo demais**: resista à tentação; safe Rust resolve 99% dos problemas

### Timeline de transição: C++ para Rust

| Fase | Duração | Foco |
|------|---------|------|
| Fundamentos | 2-3 semanas | Ownership, borrowing, enums, pattern matching |
| Intermediário | 3-4 semanas | Traits, generics, lifetimes, error handling |
| Avançado | 4-6 semanas | Async, unsafe (quando necessário), macros, FFI |
| Produtivo | 2-3 meses total | Contribuir em projetos reais |

---

## Transição de Java para Rust

### Mapeamento de conceitos

| Java | Rust | Notas |
|------|------|-------|
| `interface` | `trait` | Mais poderoso que interfaces |
| `class` | `struct` + `impl` | Sem herança |
| Generics (`<T>`) | Generics (`<T>`) | Monomorfizados em Rust |
| `try/catch` | `Result<T, E>` | Sem exceções |
| `null` | `Option<T>` | Null safety em compilação |
| GC (Garbage Collector) | Ownership + RAII | Determinístico |
| `Collections.synchronizedList` | `Arc<Mutex<Vec<T>>>` | Explícito |
| Packages | Modules + Crates | Sistema de módulos |
| Maven/Gradle | Cargo | Similar em propósito |
| JUnit | `#[test]` built-in | Testes integrados |
| `final` variável | `let` (imutável padrão) | Mutabilidade explícita |

### O que muda

**1. Sem garbage collector**

```rust
// Em Java, o GC cuida de tudo
// String s = new String("Olá"); // GC libera quando não houver referências

// Em Rust, ownership determina quando a memória é liberada
fn exemplo() {
    let s = String::from("Olá"); // s é alocado no heap
    processar(s);                 // ownership movido para processar()
    // s não é mais válido aqui - memória será liberada quando processar() terminar
}

fn processar(texto: String) {
    println!("{}", texto);
} // texto (e a memória) são liberados aqui
```

**2. Enums com dados (Algebraic Data Types)**

```rust
// Em Java: hierarquia de classes + visitor pattern
// Em Rust: enum elegante com pattern matching

#[derive(Debug)]
enum Forma {
    Circulo { raio: f64 },
    Retangulo { largura: f64, altura: f64 },
    Triangulo { base: f64, altura: f64 },
}

impl Forma {
    fn area(&self) -> f64 {
        match self {
            Forma::Circulo { raio } => std::f64::consts::PI * raio * raio,
            Forma::Retangulo { largura, altura } => largura * altura,
            Forma::Triangulo { base, altura } => base * altura / 2.0,
        }
    }

    fn descricao(&self) -> String {
        match self {
            Forma::Circulo { raio } =>
                format!("Círculo com raio {:.2}", raio),
            Forma::Retangulo { largura, altura } =>
                format!("Retângulo {}x{}", largura, altura),
            Forma::Triangulo { base, altura } =>
                format!("Triângulo com base {} e altura {}", base, altura),
        }
    }
}
```

**3. Sem exceções: Result e o operador ?**

```rust
use std::fs;
use std::io;
use std::num::ParseIntError;

#[derive(Debug)]
enum MeuErro {
    Io(io::Error),
    Parse(ParseIntError),
}

impl From<io::Error> for MeuErro {
    fn from(e: io::Error) -> Self { MeuErro::Io(e) }
}

impl From<ParseIntError> for MeuErro {
    fn from(e: ParseIntError) -> Self { MeuErro::Parse(e) }
}

// O operador ? propaga erros automaticamente (equivalente a try/catch)
fn somar_arquivo(caminho: &str) -> Result<i64, MeuErro> {
    let conteudo = fs::read_to_string(caminho)?; // propaga io::Error
    let mut soma: i64 = 0;
    for linha in conteudo.lines() {
        let num: i64 = linha.trim().parse()?; // propaga ParseIntError
        soma += num;
    }
    Ok(soma)
}

fn main() {
    match somar_arquivo("numeros.txt") {
        Ok(soma) => println!("Soma: {}", soma),
        Err(e) => eprintln!("Erro: {:?}", e),
    }
}
```

### Armadilhas comuns para programadores Java

1. **Tentar criar hierarquias de classes**: Rust não tem herança. Use traits e composição
2. **Esperar que tudo esteja no heap**: Rust aloca na stack por padrão; use `Box` quando precisar do heap
3. **Clonar tudo para evitar o borrow checker**: aprenda a trabalhar com referências
4. **Querer ponteiros nulos**: use `Option<T>` em vez de `null`
5. **Criar getters/setters para tudo**: em Rust, campos públicos são aceitáveis quando faz sentido
6. **Não aproveitar pattern matching**: `match` é muito mais poderoso que `switch`

### Timeline de transição: Java para Rust

| Fase | Duração | Foco |
|------|---------|------|
| Fundamentos | 3-4 semanas | Ownership, sem GC, enums, Option/Result |
| Intermediário | 4-5 semanas | Traits, generics, lifetimes, iterators |
| Avançado | 5-7 semanas | Async/await, macros, concorrência |
| Produtivo | 3-4 meses total | Construir projetos reais |

---

## Transição de Python para Rust

### Mapeamento de conceitos

| Python | Rust | Notas |
|--------|------|-------|
| Tipagem dinâmica | Tipagem estática forte | Tipos definidos em compilação |
| `list` | `Vec<T>` | Vetor tipado |
| `dict` | `HashMap<K, V>` | Chave e valor tipados |
| `tuple` | `(T1, T2, ...)` | Tuplas tipadas |
| `class` | `struct` + `impl` | Sem herança |
| `try/except` | `Result<T, E>` | Sem exceções |
| `None` | `Option<T>::None` | Type-safe |
| `with` (context manager) | RAII / `Drop` trait | Liberação automática |
| Decorators | Macros de atributo | `#[derive(...)]`, `#[test]` |
| List comprehensions | Iterators + collect | Funcional e lazy |
| pip/virtualenv | Cargo | Gerenciamento de dependências |
| `__init__.py` | `mod.rs` / `lib.rs` | Sistema de módulos |

### O que muda

**1. Tipagem estática com inferência**

```rust
// Python: tipos dinâmicos
// x = 42
// x = "agora sou string"  # OK em Python

// Rust: tipos estáticos, mas com inferência inteligente
fn main() {
    let x = 42;              // tipo i32 inferido
    // x = "string";         // ERRO! x é i32
    let y: f64 = 3.14;       // tipo explícito
    let z = vec![1, 2, 3];   // Vec<i32> inferido

    // Iterators são como list comprehensions
    // Python: quadrados = [x**2 for x in range(10) if x % 2 == 0]
    let quadrados: Vec<i32> = (0..10)
        .filter(|x| x % 2 == 0)
        .map(|x| x * x)
        .collect();
    println!("{:?}", quadrados); // [0, 4, 16, 36, 64]
}
```

**2. Sem garbage collector e sem alocação implícita**

```rust
fn main() {
    // Em Python, tudo é objeto no heap com refcount
    // Em Rust, dados simples ficam na stack

    let x = 42;                        // stack
    let nome = String::from("Rust");   // heap (String é alocado)
    let ref_nome = &nome;              // stack (referência para nome)

    // Clonar é explícito
    let copia = nome.clone();          // nova alocação no heap

    println!("{} {}", ref_nome, copia);
}
```

**3. Concorrência segura em vez de GIL**

```rust
use std::thread;
use std::sync::{Arc, Mutex};

fn main() {
    // Python tem o GIL que impede paralelismo real com threads
    // Rust tem concorrência real e segura

    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 || {
            let mut num = contador.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("Resultado: {}", *contador.lock().unwrap()); // 10
}
```

**4. Pattern matching avançado**

```rust
#[derive(Debug)]
enum Comando {
    Sair,
    Mover { x: i32, y: i32 },
    Escrever(String),
    MudarCor(u8, u8, u8),
}

fn executar(cmd: Comando) {
    match cmd {
        Comando::Sair => println!("Saindo..."),
        Comando::Mover { x, y } if x > 0 && y > 0 =>
            println!("Movendo para quadrante 1: ({}, {})", x, y),
        Comando::Mover { x, y } =>
            println!("Movendo para ({}, {})", x, y),
        Comando::Escrever(texto) =>
            println!("Escrevendo: {}", texto),
        Comando::MudarCor(r, g, b) =>
            println!("Cor: #{:02x}{:02x}{:02x}", r, g, b),
    }
}
```

### Armadilhas comuns para programadores Python

1. **Esperar tipagem dinâmica**: tudo precisa ter tipo definido em compilação
2. **Querer REPL interativo**: use `cargo run` ou ferramentas como `evcxr` para REPL
3. **Não entender stack vs. heap**: em Python tudo é heap; em Rust você controla
4. **Frustração com o borrow checker**: é normal no início. Persista!
5. **Tentar usar herança**: use traits e composição
6. **Querer duck typing**: em Rust, use traits para polimorfismo
7. **Usar `.unwrap()` em tudo**: trate erros adequadamente com `?` e `match`
8. **Não aproveitar o sistema de tipos**: use enums e structs para modelar o domínio

### Timeline de transição: Python para Rust

| Fase | Duração | Foco |
|------|---------|------|
| Fundamentos | 4-6 semanas | Tipagem estática, ownership, compilação |
| Intermediário | 5-7 semanas | Traits, generics, error handling, iterators |
| Avançado | 6-8 semanas | Lifetimes, async, macros |
| Produtivo | 4-5 meses total | Projetos reais e contribuições |

---

## Transição de Go para Rust

### Mapeamento de conceitos

| Go | Rust | Notas |
|----|------|-------|
| `interface` | `trait` | Traits são mais explícitos |
| Goroutines | `async/await` + `tokio::spawn` | Sem runtime embutido |
| Channels | `mpsc::channel`, `tokio::sync` | Canais tipados |
| `error` interface | `Result<T, E>` | Mais expressivo |
| `nil` | `Option<T>` | Type-safe |
| `struct` | `struct` | Similar |
| `go fmt` | `rustfmt` | Formatação automática |
| `go test` | `cargo test` | Testes integrados |
| Slices `[]T` | Slices `&[T]`, `Vec<T>` | Ownership explícito |
| `make(map[K]V)` | `HashMap::new()` | Similar |
| `defer` | `Drop` trait (RAII) | Automático via escopo |
| `go build` | `cargo build` | Similar |
| Modules (`go.mod`) | `Cargo.toml` | Similar |

### O que muda

**1. Sem garbage collector (mas sem gerenciamento manual)**

```rust
// Go: GC cuida de tudo
// Rust: ownership cuida de tudo

fn processar() -> Vec<String> {
    let mut resultados = Vec::new(); // alocado no heap

    for i in 0..10 {
        let item = format!("item_{}", i); // String alocada
        resultados.push(item); // ownership movido para o Vec
    }

    resultados // ownership retornado para o chamador
} // Nada é liberado aqui; o chamador agora é o dono
```

**2. Enums são ADTs (não apenas constantes)**

```rust
// Go: type errors com strings
// if err != nil { return err }

// Rust: erros tipados e expressivos
#[derive(Debug)]
enum ErroDeApi {
    NaoEncontrado { recurso: String },
    NaoAutorizado,
    ErroInterno(String),
    Timeout { segundos: u64 },
}

impl std::fmt::Display for ErroDeApi {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            ErroDeApi::NaoEncontrado { recurso } =>
                write!(f, "Recurso não encontrado: {}", recurso),
            ErroDeApi::NaoAutorizado =>
                write!(f, "Não autorizado"),
            ErroDeApi::ErroInterno(msg) =>
                write!(f, "Erro interno: {}", msg),
            ErroDeApi::Timeout { segundos } =>
                write!(f, "Timeout após {} segundos", segundos),
        }
    }
}
```

**3. Generics completos (não apenas a partir de Go 1.18)**

```rust
use std::collections::HashMap;
use std::hash::Hash;

// Generics com trait bounds claros
fn contar_frequencia<T: Hash + Eq>(items: &[T]) -> HashMap<&T, usize> {
    let mut freq = HashMap::new();
    for item in items {
        *freq.entry(item).or_insert(0) += 1;
    }
    freq
}

// Equivalente a generics de Go, mas mais poderoso
fn maximo<T: PartialOrd>(a: T, b: T) -> T {
    if a >= b { a } else { b }
}
```

**4. Concorrência: explícita e verificada em compilação**

```rust
use tokio::sync::mpsc;

// Equivalente a goroutines + channels
#[tokio::main]
async fn main() {
    let (tx, mut rx) = mpsc::channel::<String>(100);

    // "Goroutines" com tokio::spawn
    for i in 0..5 {
        let tx = tx.clone();
        tokio::spawn(async move {
            let msg = format!("Mensagem {}", i);
            tx.send(msg).await.unwrap();
        });
    }

    drop(tx); // Fechar o canal original

    // Receber mensagens
    while let Some(msg) = rx.recv().await {
        println!("Recebido: {}", msg);
    }
}
```

### Armadilhas comuns para programadores Go

1. **Querer usar `nil`**: Rust usa `Option<T>` e isso é verificado em compilação
2. **Esperar interfaces implícitas**: em Rust, `impl Trait for Type` é explícito
3. **Usar goroutines como threads**: `tokio::spawn` requer `async`, é um modelo diferente
4. **Esperar um runtime embutido**: Rust não tem runtime; você escolhe (tokio, async-std)
5. **Ignorar lifetimes**: Go não tem esse conceito; em Rust é essencial entender
6. **Não usar pattern matching**: `match` substitui cadeias de `if err != nil`

### Timeline de transição: Go para Rust

| Fase | Duração | Foco |
|------|---------|------|
| Fundamentos | 2-3 semanas | Ownership, enums, traits explícitas |
| Intermediário | 3-4 semanas | Generics, lifetimes, error handling |
| Avançado | 4-5 semanas | Async (tokio), macros, unsafe |
| Produtivo | 2-3 meses total | Projetos reais |

---

## Transição de JavaScript/TypeScript para Rust

### Mapeamento de conceitos

| JS/TS | Rust | Notas |
|-------|------|-------|
| TypeScript types | Tipos nativos | Verificação em compilação |
| `interface` (TS) | `trait` | Similar |
| `class` | `struct` + `impl` | Sem herança |
| `Promise` | `Future` | Async/await similar |
| `async/await` | `async/await` | Sintaxe muito similar |
| `npm`/`yarn` | `cargo` | Similar |
| `package.json` | `Cargo.toml` | Similar |
| `null`/`undefined` | `Option<T>` | Type-safe |
| `try/catch` | `Result<T, E>` | Sem exceções |
| `Array.map/filter` | `Iterator::map/filter` | Lazy em Rust |
| Closures `=>` | Closures `\|\|` | Com ownership |
| `console.log` | `println!` | Macro em Rust |
| Destructuring | Pattern matching | Mais poderoso em Rust |
| `const`/`let` | `let`/`let mut` | Imutável por padrão |

### O que muda

**1. Sem runtime, sem event loop implícito**

```rust
// JavaScript: event loop implícito
// fetch(url).then(r => r.json()).then(data => console.log(data));

// Rust: runtime explícito (tokio)
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let resp = reqwest::get("https://api.exemplo.com/dados")
        .await?
        .json::<serde_json::Value>()
        .await?;

    println!("{:#?}", resp);
    Ok(())
}
```

**2. Closures com ownership**

```rust
fn main() {
    let nome = String::from("Rust");

    // Closure que empresta (padrão)
    let saudar = || println!("Olá, {}!", nome);
    saudar();
    println!("nome ainda válido: {}", nome);

    // Closure que move ownership
    let nome2 = String::from("Brasil");
    let saudar_move = move || println!("Olá, {}!", nome2);
    saudar_move();
    // println!("{}", nome2); // ERRO! nome2 foi movido

    // Closure que muta
    let mut numeros = vec![1, 2, 3];
    let mut adicionar = || numeros.push(4);
    adicionar();
    println!("{:?}", numeros); // [1, 2, 3, 4]
}
```

**3. Iterators são lazy (como generators)**

```rust
fn main() {
    // JavaScript: arrays são eager
    // const result = [1,2,3,4,5].filter(x => x > 2).map(x => x * 2);

    // Rust: iterators são lazy, só executam ao consumir
    let resultado: Vec<i32> = vec![1, 2, 3, 4, 5]
        .into_iter()
        .filter(|x| *x > 2)
        .map(|x| x * 2)
        .collect(); // aqui que a cadeia é executada

    println!("{:?}", resultado); // [6, 8, 10]

    // Equivalente a reduce
    let soma: i32 = (1..=100).sum();
    println!("Soma: {}", soma); // 5050

    // Chaining complexo
    let texto = "rust é incrível e rust é seguro";
    let palavras_unicas: Vec<&str> = texto
        .split_whitespace()
        .collect::<std::collections::HashSet<_>>()
        .into_iter()
        .collect();
    println!("{:?}", palavras_unicas);
}
```

**4. Serialização com serde (equivalente a JSON nativo)**

```rust
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
struct Usuario {
    nome: String,
    email: String,
    idade: u32,
    #[serde(default)]
    ativo: bool,
}

fn main() -> Result<(), serde_json::Error> {
    // JSON para struct (como JSON.parse com tipos)
    let json = r#"{"nome": "Maria", "email": "maria@rust.br", "idade": 28}"#;
    let usuario: Usuario = serde_json::from_str(json)?;
    println!("{:?}", usuario);

    // Struct para JSON (como JSON.stringify)
    let json_saida = serde_json::to_string_pretty(&usuario)?;
    println!("{}", json_saida);

    Ok(())
}
```

### Armadilhas comuns para programadores JavaScript

1. **Esperar tipagem dinâmica**: Rust é estritamente tipado
2. **Querer protótipos/herança**: use traits e composição
3. **Ignorar ownership**: o conceito mais diferente de JS
4. **Esperar coerção automática**: Rust não converte tipos implicitamente
5. **Usar `.unwrap()` como se fosse try/catch genérico**: trate erros especificamente
6. **Não entender a diferença entre `String` e `&str`**: `String` é owned, `&str` é emprestado
7. **Querer null/undefined**: use `Option<T>`
8. **Esquecer que closures têm regras de ownership**: closures em Rust capturam variáveis com regras

### Timeline de transição: JavaScript para Rust

| Fase | Duração | Foco |
|------|---------|------|
| Fundamentos | 4-5 semanas | Tipos estáticos, ownership, compilação |
| Intermediário | 5-6 semanas | Traits, generics, error handling |
| Avançado | 6-8 semanas | Lifetimes, async runtime, macros |
| Produtivo | 4-5 meses total | Projetos reais |

---

## Comparação de Timelines

| Linguagem de Origem | Tempo até Produtivo | Dificuldade |
|---------------------|---------------------|-------------|
| C++ | 2-3 meses | Baixa-Média |
| Go | 2-3 meses | Média |
| Java | 3-4 meses | Média |
| Python | 4-5 meses | Alta |
| JavaScript | 4-5 meses | Alta |

A dificuldade varia porque:
- **C++** já lida com gerenciamento de memória manual e conceitos similares
- **Go** é compilada e tipada, mas não tem ownership
- **Java** é OOP forte; a maior mudança é sair de herança e GC
- **Python/JS** são dinâmicas e com GC; a maior distância conceitual

---

## Recursos para Cada Transição

### Para todos

- [The Rust Programming Language](https://doc.rust-lang.org/book/) (o Rust Book)
- [Rust by Example](https://doc.rust-lang.org/rust-by-example/)
- [Rustlings](https://github.com/rust-lang/rustlings) (exercícios interativos)
- [Exercism Rust Track](https://exercism.org/tracks/rust)

### Específicos por linguagem

**De C++:**
- "Rust for C++ Programmers" (artigo da equipe Rust)
- Comparação de smart pointers C++ vs Rust

**De Java:**
- "Rust for Java Developers" (série de artigos)
- Foco em traits vs interfaces, enums vs class hierarchy

**De Python:**
- "Rust for Pythonistas" (tutorial)
- PyO3 para integrar Rust com Python
- [Python Brasil](https://python.dev.br) — aprofunde-se em Python e combine com Rust via PyO3

**De Go:**
- "Rust for Gophers" (artigo)
- Comparação de concorrência Go vs Rust
- [Go Brasil](https://golang.com.br) — mantenha-se atualizado em Go enquanto aprende Rust

**De JavaScript:**
- "Rust for JavaScript Developers" (série)
- WebAssembly como ponte entre JS e Rust
- Neon para escrever módulos Node.js em Rust

---

## Conclusão

A transição para Rust é um investimento que vale a pena independentemente da sua linguagem de origem. Os pontos-chave para uma transição bem-sucedida são:

- **Aceite o borrow checker como aliado**: ele está te impedindo de criar bugs, não de programar
- **Não tente escrever [linguagem anterior] em Rust**: abrace os idiomas da linguagem
- **Comece com projetos pequenos**: ferramentas CLI são excelentes para aprender
- **Leia código de outros**: explore crates populares e projetos open source
- **Participe da comunidade**: a comunidade Rust é conhecida por ser acolhedora
- **Seja paciente**: os primeiros 2-4 semanas são os mais difíceis; depois, o compilador se torna seu melhor amigo

A curva de aprendizado do Rust é real, mas é uma curva --- não um muro. Cada desenvolvedor que fez a transição relata que, depois de internalizá-la, não quer voltar. O investimento inicial se paga em código mais seguro, mais rápido e mais confiável.
