Language Agnostic

De Java a Rust em 90 dias

O framework mental para aprender qualquer linguagem rapidamente

5 de fev. de 2026·Ricardo Coelho

A pergunta que aparece com regularidade em conversas de carreira é sobre prazo: em quanto tempo um engenheiro com dez anos de Java consegue operar em Rust num nível produtivo. Na minha avaliação, o prazo varia menos com a linguagem de destino do que com a estrutura do processo de aprendizado, e noventa dias é uma janela realista pra maioria das transições, desde que o engenheiro resista à tentação de estudar a linguagem nova como se fosse a primeira. O erro mais comum está em tratar Rust como território desconhecido quando boa parte do que ele contém é reconfiguração sintática de conceitos que o engenheiro já opera há uma década.

Pra mim, o framework que produz transição rápida começa pela separação explícita entre o que transfere e o que não transfere. Estruturas de dados, algoritmos, modelagem de domínio, design de API, testes, arquitetura de serviços, concorrência em nível conceitual, sistemas de tipos: tudo isso transfere de Java pra Rust com perda marginal. O engenheiro que já entendeu generics, interfaces, imutabilidade e composição em Java encontra em Rust equivalentes diretos com sintaxe diferente: traits no lugar de interfaces, generics com bounds no lugar de generics com extends, enums algébricos que expandem o que sealed classes passaram a oferecer a partir do Java 17. A transferência aqui é literal, com renomeação. Tratar essa camada como novidade desperdiça semanas que deveriam estar sendo investidas onde a transferência falha.

A transferência falha em três pontos identificáveis, e é neles que os noventa dias precisam ser concentrados. O primeiro é o modelo de ownership e borrow checker. Rust substitui garbage collection por um sistema onde a posse de cada valor é rastreada estaticamente, e onde referências carregam lifetimes que o compilador verifica. Pra um engenheiro de Java, isso não é uma feature adicional, mas uma reconfiguração do modelo mental de memória. Compartilhar estado mutável entre partes do programa ou construir ciclos de objetos mantendo referências enquanto a estrutura subjacente é modificada: tudo isso é rotina em Java e passa a ser erro de compilação em Rust. O segundo ponto é a ausência de exceções como mecanismo de controle de fluxo. Result e Option substituem try/catch, e o que era um efeito lateral implícito vira um valor explícito que precisa ser propagado. O terceiro ponto é a concorrência, onde Send e Sync tornam visíveis no sistema de tipos as garantias que em Java ficam sustentadas por convenção ou documentação até virarem bug em produção.

A distribuição do tempo nos noventa dias segue dessa separação. As primeiras duas semanas devem ser dedicadas exclusivamente a ownership, borrowing e lifetimes, escrevendo código pequeno e apanhando do compilador. Pular essa etapa pra construir algo útil é o erro que mais alonga o prazo total: o engenheiro reescreve as mesmas estruturas três ou quatro vezes conforme descobre restrições que deveria ter internalizado antes. As semanas três e quatro entram em Result, Option, pattern matching e traits, onde o idioma de Rust começa a aparecer como distinto de Java. A partir da quinta, o engenheiro constrói algo não trivial (um serviço, uma CLI, uma biblioteca) e a velocidade sobe, porque a fundação já foi paga. Entre a oitava e a décima, a concorrência entra com async/await, Tokio (o runtime assíncrono padrão de Rust) e os traits de sincronização. As últimas semanas são calibragem: idioms, tooling, Clippy (o linter oficial do Rust), perfil de performance, transição de código que compila pra código que um revisor de Rust aprovaria.

O atrito real nesse processo está na tolerância a operar, por semanas, com uma produtividade menor que a habitual. Um engenheiro sênior de Java está acostumado a resolver problemas em horas; em Rust, nas primeiras semanas, ele vai passar tardes inteiras discutindo com o borrow checker sobre estruturas que construiria em minutos na linguagem de origem. Essa queda é reversível, mas produz um efeito de identidade que desvia muitos engenheiros: a sensação de incompetência temporária leva à racionalização de que a linguagem é inadequada, o que encerra o processo antes da curva virar. Na minha análise, reconhecer essa fase como parte esperada do mecanismo é o que separa engenheiros que completam a transição dos que desistem na quarta semana.

O framework vale pra qualquer transição, não apenas Java pra Rust. A estrutura é a mesma. Começa por identificar o que transfere diretamente e isolar os dois ou três pontos onde o modelo mental precisa ser reconfigurado. Em seguida, investe-se tempo desproporcional neles no início, aceitando a queda temporária de produtividade como custo contabilizado. Em Go, a curva colapsa em torno de goroutines, channels e um sistema de tipos deliberadamente minimalista. Em Elixir, a concentração está em imutabilidade estrutural, pattern matching pesado e modelo de atores; Haskell exige reconfiguração de efeitos, monads e avaliação preguiçosa. Cada linguagem tem uma superfície pequena de conceitos novos cercada por uma superfície maior de equivalências que o engenheiro já conhece sob outros nomes. Noventa dias é suficiente quando o tempo é alocado pela densidade do que é genuinamente novo.

Sources: