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.