Rust e o "empréstimo" de propriedade
Tags: rust, codenewbie, beginners, braziliandevs
Published: 2022-06-30 16:37:00

 
  Um conceito fundamental de Rust é sua base de como a linguagem lida com dados. A ideia de ownership em Rust é literalmente definir um 'dono" para cada valor, se o dono do valor sai de escopo, este valor é 'solto'. Essa regra faz com que o compilador de Rust evite erros como de apontador pendente, onde um ponteiro aponta para um local inválido na memória, ou outros erros de comportamento como liberar o mesmo endereço de memória mais de uma vez como o uso de `free()` da linguagem C.
Mesmo com suas regras mais estritas, Rust oferece certa flexibilidade com recursos extras de gerenciamento. 

  Um desses recursos é o empréstimo de propriedade, ou ownership borrowing em inglês. 
Temporariamente, um valor pode ser emprestado para outra variável durante seu ciclo de vida sem a necessidade da troca de proprietário. 
Isso é possível com o que Rust chama de referência, muito parecido com um `pointer` de C/C++, uma referência aponta para o endereço de memória onde esta o valor armazenado, a diferença para um `pointer` é que a referência sempre aponta para um endereço válido.
Isso é feito com o uso do `&` (conhecido como E comercial ou ampersand em inglês). 

---

  Funciona assim, vamos declarar a função main, com a variável `i` que contém a String "String exemplo", realizamos a impressão de `i` e fechamos o escopo.
Sem realizar o empréstimo de `i`, usando o `&`, não seria possível realizar a impressão de `i` dentro da função empréstimo. 

```
fn main() {
    let i = String::from("String exemplo");
    emprestimo(&i);
    println!("Valor em main: {}", i);
}
fn emprestimo(i: &String) {   
    println!("Valor emprestado: {}", i);
}

```


  Porém, como indicamos isso com `&`, então é possível compilar e ter a impressão de `i` realizada em ambas funções sem a necessidade da troca de proprietário (`i`).

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iop5ywvbh31m8cmb0n0n.png)

Sem realizar esse empréstimo de valor, o compilador já nos orientaria o norte correto. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/egv4n6nx3aqyf1s33p95.png)

---

  Uma dificuldade que pode ser encontrada nesse tipo de empréstimo do valor é não ser possível a alteração do valor em questão, **por padrão**, variáveis são **imutáveis** em Rust, logo referências também serão imutáveis. 
Por isso, assim como é possível tornar variáveis mutáveis, referências idem, com o uso da keyword `mut` junto a `&`. 

Tornando uma referência mutável, ao emprestar o valor, o proprietário temporário pode exclusivamente alterar esse valor. 
Importantíssimo notar que enquanto tenho uma referência mutável ativa, não se pode ter qualquer outro tipo de empréstimo no dado valor.

Isso previne erros do tipo "data race", um problema da programação multitarefa onde uma tarefa ou processo precisa acessar um valor compartilhado e desprotegido, e geralmente situações imprevisíveis acontecem com o resultado. 

Uma data race seria duas tarefas que escrevem um valor na nossa variável `i`, digamos 30 na tarefa A, e 5 na tarefa B, e depois realizam um cálculo que retorna o valor de `i`.
O valor retornado pode ser tanto 30, como 5, ou até então um valor quebrado. 

Isso não acontece em Rust justamente pela proteção de somente existir uma mutabilidade ocorrendo no valor em determinado período.