O borrowing permitir ter múltiplas referências a um recurso ao mesmo tempo, aderindo um conteúdo proprietário único em um local de responsabilidade, podemos pegar com base os ponteiros em C.

O borrowing trabalha com as suas referências, vale lembrar que é um objeto então eles podem ser mutáveis assim são movidos e imutáveis que são apenas copiados.

Exemplo abaixo.


fn main() {
    let texto = String::from("google");

    let tamanho = calcula_tamanho(&texto);

    println!("O texto é: '{}' de tamanho {}.", texto, tamanho);
}

fn calcular(texto: &String) -> usize {
    texto.len()
}

/*
  O texto é: 'google' de tamanho 6.
*/

No exemplo acima a finalidade do código e saber quantas letras tem o texto “google”, temos uma função chamada calcular que retorna o tamanho da string passada por parâmetro veja que na função passamos uma string.

O & são a referências. é uma forma de passar o dado sem que tome posse dele.

O &texto nos permitir criar uma referência, mas sem posse após a contagem o valor não é destruído por sair do escopo.

E se no caso tentarmos modificar o valor emprestado ?


fn main() {
    let texto = String::from("google");

    calcula_tamanho(&texto);
}

fn calcula_tamanho(texto: &String)  {
    texto.push_str(" vou pesquisar");
}


/*
  error[E0596]: cannot borrow immutable borrowed content `*texto` as mutable
 --> main.rs:8:5
  |
7 | fn calcula_tamanho(texto: &String)  {
  |                           ------- use `&mut String` here to make mutable
8 |     texto.push_str(" vou pesquisar");
  |     ^^^^^ cannot borrow as mutable
*/

Como já imaginava, aquele error onde a variável não é mutável. No console o informa “&mut String here to make mutable” como fazer uma variável mutável.

Vamos para um exemplo mutável.


fn main() {
  let mut pesquisar = String::from("google");

  modifica(&mut pesquisar);

  print!("Pesquisa: {}", pesquisar);
}

fn modifica(texto: &mut String) {
  texto.push_str(" pokemon");
}

/*
  Pesquisa: google pokemon
*/

Estamos alterando a variável pesquisar que declaramos como mut após isso, na função um parâmetro string com referência a variável mutável assim conseguimos alterar com base na chamada.

As referências mutáveis tem restrições.


fn main() {
  let mut texto = String::from("texto");
  let texto_2 = &mut texto;
  let texto_3 = &mut texto;
}

/*
error[E0499]: cannot borrow `texto` as mutable more than once at a time
 --> main.rs:4:22
  |
3 |   let texto_2 = &mut texto;
  |                      ----- first mutable borrow occurs here
4 |   let texto_3 = &mut texto;
  |                      ^^^^^ second mutable borrow occurs here
5 | }
  | - first borrow ends here
*/

A maioria das linguagens de programação permiti modificar um valor quando você quiser, só que no Rust não irá, pois é uma forma da linguagem evitar erros do tipo data races.

Um data race é parecido com uma condição de corrida, e acontece quando esses três fatores ocorrem: Dois ou mais ponteiros acessam o mesmo dado ao mesmo tempo. Ao menos um dos ponteiros é usado para escrever sobre o dado. Não há nenhum mecanismo sendo usado para sincronizar o acesso ao dado.

Então para referências existe regras que um dado só pode ter um ou o outro, mas não os dois.

Então galera é isso, espero que tenham gostado até a próxima.