Matheus Garcia
Matheus Garcia26/05/2026 00:34
Compartilhe

Ownership e Borrowing 🦀

    Se você está estudando Rust, você já deve ter ouvido fala de como é uma linguagem eficiente, rápida e principalmente, segura. Neste tópico vamos entender um pouco mais do que tornou Rust o que é hoje.

    Segurança pra que?

    Desenvolver softwares de sistema não é lá a tarefa mais fácil que existe, exige um controle restrito dos recursos do sistema, principalmente a memória de nosso computador (o maior causador de bugs em sistemas), você iria precisar de linguagens que oferececem este controle, como C/C++, mas com isso também vem os riscos de manipulara a memória manualmente.

    Este não é um problema novo, as linguagens no passado já viriam a tentar resolver este problema, você deve conhecer o Garbage Collector certo? Um programa que roda em runtime na sua aplicação e verifica o que pode ser desalocado da memória, então problema resolvido... certo?

    GC não era exatamente a melhor alternativa para lidar com memória, principalmente para sistemas onde o controle e desempenho são críticos, um sistema que roda em runtime consome recursos desnecessários e é imprevisivel, então não são uma alternativa viável a C/C++, era preciso algo mais, foi quando nasceu Rust.

    Ownership e Borrowing

    Então vamos apresentar o que é esse tal de Ownership, e porque com ele a segurança pode ser garantida sem sacrificar desempenho e controle.

    O Ownership é um conjunto de regras que regem como programas em Rust gerenciam memória, sendo as regras:

    • Todo Objeto tem um dono;
    • Todo Objeto só pode ter um dono por vez;
    • Quando o dono sai de escopo, o objeto é desalocado (morre!);

    Vamos a um exemplo:

    fn main() {
    let owner = String::from("i'm owner!"); // aqui, 'owner' é dono da string
                                            // "i'm owner", ele tem sua posse!
    {
      let new_owner = owner;  // aqui pode confundir muita gente, o valor de
                              // owner não é copiado para new_owner... ele
                              // da a posse de "i'm owner" para new_owner!
    
      // aqui new_owner sai de escopo, consequentemente
      // "i'm string" é desalocada (morre!)
    }
    
    println!("{}", owner);   // panic! owner aqui não é dono de nada! (coitado...)
    }
    

    Este exemplo bem simples (e bobo) mostra como Ownership funciona em Rust.

    Beleza, mas ai temos um problema, quando eu for passar um objeto de parametro para uma função, eu sempre vou perder a posse? Talvez Rust não seja tão bom assim...

    Calma! Rust sabe disso, e tem a solução perfeita para este problema: Borrowing!

    Para entender Borrowing, precisamos entender referências. Quem já programou em C/C++ está familiarizado com isso, mas irei explicar de qualquer forma, referências são a localização de onde nosso objeto está armazenado na memória, precisamos dizer ao Rust onde podemos encontrá-lo. Quando passamos um objeto por referência, não estamos dando sua posse, estamos emprestando! Isso mesmo, Borrowing!

    Vejamos o mesmo exemplo anterior, mas agora com referências:

    fn main() {
    let owner = String::from("i'm owner!"); // aqui, 'owner' é dono da string
                                            // "i'm owner", já sabemos.
    {
      let new_owner = &owner;  // aqui estamos emprestando a string de 'owner'
                               // de forma que ele pode utiliza-lá enquanto
                               // estiver em escopo, e quando sair de escopo,
                               // "i'm owner!" retorna para owner!
      println!("{}", new_owner);
    }
    
    println!("{}", owner);   // tudo certo por aqui
    }
    

    Este exemplo mostra como conseguimos utilizar um objeto em outro local do nosso código sem perder sua posse! Uau!

    Mas vamos com muita calma, a posse que passamos era apenas para leitura, não poderiamos alterar o objeto. Isso não é o suficiente! Quantas vezes programando não queremos apenas ler, mas também modificar um valor? Para isso a referência precisa ser mutável.

    Se você chegou até o Ownership e Borrow Checker, você provavelmente passou pela mutabilidade de Rust (let mut) e como os dados são imutáveis por padrão, o mesmo vale para referências!

    Mas muita atenção aqui! Referências são diferentes de objetos, quando você passa referências imutáveis, você pode emprestá-las para quantos objetos quizer, numa relação de 1 -> N, é lógico, quem emprestou seu objeto está apenas lendo ele, que mal tem? A história é diferente para referências mutáveis, aqui a relação é de 1 -> 1, ou seja, você só pode emprestar uma referência mutável por vez.

    Essa abordagem veio para resolver problemas de concorrência e multiprogramação, vejamos dois exemplos de referências mutáveis:

    fn main() {
    let mut owner = String::from("i'm owner!");
    
    {
      let new_owner = &mut owner;    // aqui podemos alterar o valor de 'owner'
      new_owner.push_str(" yooooo"); // mesmo sem ter sua posse!
    }
    
    println!("{}", owner);   // saida: "i'm owner! yooooo"
    }
    
    fn main() {
    let mut owner = String::from("i'm owner!");
    
    {
      let new_owner = &mut owner;     // aqui temos duas referencias mutaveis
      let other_owner = &mut owner;   // de uma vez, para 'other_owner' funcionar
                                      // 'new_owner' deve realizar sua operacao
                                      // ou sair de escopo!
      
      new_owner.push_str(" yooooo");
      other_owner.push_str(" yesss"); // panic!
    }
    
    
    println!("{}", owner);
    }
    

    Considerações Finais

    Bem, aqui cobrimos o fundamental para ter um bom entendimento do sistema de memória de Rust, é claro, isso não é tudo, ainda não abordamos lifetimes! Mas isso pode ficar para outra hora, deixo aqui meu agradecimento para quem leu até o final, e realmente gosta de Rust, como eu, um apaixonado pela linguagem.

    Também não quis me alongar sobre quais problemas Rust se propõem a resolver, pois o artigo ficaria muito grande! Quem quer enteder os problemas que Rust resolve recomendo se aventurar um pouco com C/C++, vocês não vão se arrepender!

    Para um melhor entendimento (e uma explicação mais técnica) recomendo vocês lerem o que próprio livro de Rust tem a dizer sobre o Ownership, aliais, leiam o livro todo! Não vão se arrepender!

    The book (en): https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html

    O livro (pt-br): https://rust-br.github.io/rust-book-pt-br/ch04-00-understanding-ownership.html

    Por favor deixe um feedback se este tópico te ajudou, ou se achou divertido, abraços!

    github: https://github.com/maatdeveloper

    linkedin: https://www.linkedin.com/in/matheuscgarcia/

    Compartilhe
    Comentários (0)