Article image
José Sousa
José Sousa01/06/2026 22:44
Compartilhe

🦀Rust não é difícil. Ele só te obriga a parar de programar no automático.

    Quando a gente começa a estudar Rust, a primeira reação costuma ser quase sempre a mesma:

    “Por que essa linguagem está brigando comigo?”

    Você tenta fazer algo simples, o compilador reclama.

    Você passa uma variável para uma função, ela “some”.

    Você tenta modificar um valor, o Rust pergunta se você realmente tem permissão para isso.

    Você escreve algo que em Python, JavaScript ou Java passaria tranquilo, e o compilador simplesmente barra.

    No começo parece exagero.

    Mas depois de apanhar um pouco, começa a cair a ficha: o Rust não está dificultando por capricho. Ele está te obrigando a enxergar problemas que outras linguagens muitas vezes deixam escondidos.

    E é aí que a linguagem começa a ficar interessante.

    O erro é achar que Rust é só sintaxe nova

    Muita gente começa Rust tentando traduzir mentalmente o que já sabe de outras linguagens.

    “Como faço isso aqui igual eu faria em Python?”

    “Como escrevo esse fluxo igual no Java?”

    “Como crio essa API igual no Node?”

    Esse é o primeiro tropeço.

    Rust não é só uma linguagem com sintaxe diferente. Rust tem outro modelo mental.

    Em várias linguagens, você escreve o código e só depois descobre se fez besteira. Às vezes no teste. Às vezes no log. Às vezes em produção, naquele horário maravilhoso em que ninguém queria estar acordado.

    No Rust, muita coisa que viraria bug em runtime vira erro de compilação.

    E aí vem a dor.

    Não porque a linguagem é “chata”, mas porque ela puxa para o começo do processo várias decisões que a gente costuma empurrar para depois.

    O compilador não é seu inimigo. Ele é o fiscal da obra.

    O compilador do Rust tem fama de rigoroso, e com razão.

    Mas talvez a melhor forma de enxergar isso seja pensar nele como um fiscal de obra.

    Você até pode querer subir a parede torta, improvisar a fiação e esconder o vazamento atrás do acabamento. Em muita linguagem, isso passa. O sistema sobe, a tela abre, o cliente clica e todo mundo finge que está tudo bem.

    Até não estar.

    O Rust chega antes e fala:

    “Calma lá. Quem é dono desse valor?”
    “Essa referência ainda é válida?”
    “Você vai tratar esse erro ou vai fingir que ele não existe?”
    “Tem duas partes tentando modificar a mesma coisa ao mesmo tempo?”

    Na hora irrita. Depois você entende: ele não está tentando te humilhar. Ele está tentando impedir que você entregue uma bomba-relógio com build verde.

    Ownership: a parte em que o Rust muda sua cabeça

    O conceito de Ownership é provavelmente uma das primeiras grandes pancadas.

    Em Rust, todo valor tem um dono.

    Só pode existir um dono por vez.

    Quando o dono sai de escopo, o valor é liberado.

    Parece simples lendo assim. Mas na prática, para quem vem de linguagens com Garbage Collector ou modelos mais flexíveis, isso dá um nó bonito.

    Exemplo:

    fn main() {
      let nome = String::from("Rust");
      let outro_nome = nome;
    
      println!("{}", nome);
    }
    

    Em muitas linguagens, isso seria tranquilo.

    Em Rust, não.

    Quando fazemos:

    let outro_nome = nome;
    

    A posse da String foi movida para outro_nome. O nome original não pode mais ser usado.

    E aí o compilador reclama.

    No começo você pensa: “mas por quê?”

    Depois entende: Rust quer deixar explícito quem é responsável por aquele dado.

    Nada de valor perdido no limbo.

    Nada de uso depois de liberar memória.

    Nada de duas partes mexendo no mesmo recurso sem regra clara.

    É menos “confia” e mais “prova”.

    Borrowing: porque nem tudo precisa mudar de dono

    Agora vem o alívio: nem sempre você precisa transferir a posse de um valor.

    Você pode emprestar.

    Esse é o Borrowing.

    fn mostrar_nome(nome: &String) {
      println!("{}", nome);
    }
    
    fn main() {
      let nome = String::from("Rust");
      mostrar_nome(&nome);
    
      println!("{}", nome);
    }
    

    Aqui, a função mostrar_nome só pegou uma referência. Ela não virou dona da String.

    É como dizer:

    “Pode olhar, mas não leva embora.”

    Esse detalhe muda tudo.

    Você começa a perceber que Rust não quer impedir você de programar. Ele quer que você seja explícito sobre intenção.

    Vai só ler? Usa referência imutável.

    Vai alterar? Usa referência mutável.

    Vai transferir responsabilidade? Move a posse.

    O código passa a comunicar mais.

    A regra que parece chata, mas salva muita coisa

    Uma das regras mais famosas do Rust é:

    Você pode ter várias referências imutáveis ao mesmo tempo ou uma única referência mutável.

    Não os dois juntos.

    Na prática:

    let mut texto = String::from("Olá");
    
    let a = &texto;
    let b = &texto;
    
    println!("{} {}", a, b);
    

    Tudo certo. Várias leituras simultâneas.

    Agora:

    let mut texto = String::from("Olá");
    
    let a = &mut texto;
    let b = &mut texto;
    

    Aí o compilador para o baile.

    E ele está certo.

    Porque se duas partes diferentes puderem modificar o mesmo dado ao mesmo tempo, você abriu a porta para comportamento imprevisível. Em sistemas maiores, com concorrência, threads e estado compartilhado, isso vira um parque de diversões para bugs difíceis de reproduzir.

    Rust não espera o caos acontecer. Ele fecha a porta antes.

    Rust te força a tratar erro como parte do sistema

    Outro ponto importante: Rust não gosta muito da ideia de erro escondido.

    Em vez de sair lançando exceção para todo lado, Rust trabalha muito com Result e Option.

    Um Option<T> diz:

    “Pode existir um valor aqui, ou pode não existir.”

    Um Result<T, E> diz:

    “Essa operação pode dar certo ou pode falhar.”

    Parece burocrático no começo, mas é uma das melhores coisas da linguagem.

    Porque o erro deixa de ser um susto e vira parte explícita do fluxo.

    Exemplo:

    fn dividir(a: i32, b: i32) -> Result<i32, String> {
      if b == 0 {
          Err(String::from("Não é possível dividir por zero"))
      } else {
          Ok(a / b)
      }
    }
    

    Agora quem chamar essa função precisa lidar com o resultado.

    Não dá para fingir que nada pode dar errado.

    E isso é muito forte.

    Em sistemas reais, erro ignorado vira incidente. Em Rust, pelo menos boa parte desses problemas o compilador joga na sua cara antes.

    O problema não é o Rust. É tentar escrever Rust como se fosse outra linguagem.

    Essa talvez seja a maior virada de chave.

    Se você tenta escrever Rust como se fosse JavaScript com outro compilador, vai sofrer.

    Se tenta escrever Rust como se fosse Python com chaves, vai sofrer.

    Se tenta escrever Rust como se fosse C sem ponteiro perigoso, vai sofrer também.

    Rust exige outro jeito de pensar.

    Ele te obriga a refletir sobre:

    • quem é dono do dado;
    • quem pode ler;
    • quem pode modificar;
    • quando o valor deixa de existir;
    • quais erros podem acontecer;
    • quais estados são válidos;
    • o que pode ser garantido em tempo de compilação.

    Isso não é detalhe. Isso é engenharia.

    Onde Rust começa a fazer sentido de verdade

    Rust brilha muito quando o custo do erro é alto.

    Sistemas embarcados.

    Infraestrutura.

    APIs performáticas.

    Blockchain.

    Drivers.

    Ferramentas de linha de comando.

    Sistemas concorrentes.

    Aplicações onde segurança de memória e previsibilidade importam.

    Mas mesmo para quem está começando, estudar Rust já traz um benefício enorme: ele melhora sua forma de pensar código.

    Mesmo que você volte para Java, Python, Go, C# ou JavaScript depois, você volta diferente.

    Você passa a olhar com mais atenção para estado, erro, mutabilidade, ciclo de vida e responsabilidade.

    Rust te dá uma surra, mas é uma surra educativa.

    Então Rust é difícil?

    Sim, Rust tem uma curva de aprendizado maior.

    Mas talvez a pergunta melhor seja:

    Difícil comparado com o quê?

    Difícil comparado com escrever código rápido sem pensar muito? Sim.

    Difícil comparado com debugar erro invisível em produção? Talvez não.

    Difícil comparado com caçar race condition que só acontece uma vez por semana? Definitivamente não.

    Rust cobra antes.

    E esse é o ponto.

    A linguagem antecipa discussões que em outros lugares só aparecem quando o sistema cresce, quebra ou precisa ser mantido por alguém que não estava lá no começo.

    Conclusão

    Rust não é uma linguagem que tenta agradar no primeiro contato.

    Ela não passa a mão na sua cabeça.

    Ela não deixa você empurrar problema para depois.

    Ela não confia cegamente na sua memória, na sua disciplina ou no famoso “depois eu trato isso”.

    E talvez seja exatamente por isso que ela esteja ganhando tanto espaço.

    Rust não é só sobre performance.

    É sobre controle.

    É sobre segurança.

    É sobre transformar intenção em contrato.

    É sobre fazer o compilador trabalhar a seu favor antes que o bug trabalhe contra você.

    No começo, parece que o compilador está brigando com você.

    Depois você percebe que ele só está tentando te ensinar a parar de programar no automático.

    E quando essa chave vira, Rust deixa de parecer uma linguagem difícil e começa a parecer uma linguagem honesta.

    Compartilhe
    Comentários (0)