Ferrugem - Empréstimo
É muito inconveniente passar a propriedade de uma variável para outra função e então retornar a propriedade. Rust apóia um conceito, empréstimo, onde a propriedade de um valor é transferida temporariamente para uma entidade e então devolvida à entidade proprietária original.
Considere o seguinte -
fn main(){
// a list of nos
let v = vec![10,20,30];
print_vector(v);
println!("{}",v[0]); // this line gives error
}
fn print_vector(x:Vec<i32>){
println!("Inside print_vector function {:?}",x);
}
A função principal invoca uma função print_vector () . Um vetor é passado como parâmetro para esta função. A propriedade do vetor também é passada para a função print_vector () do main () . O código acima resultará em um erro conforme mostrado abaixo quando a função main () tenta acessar o vetor v .
| print_vector(v);
| - value moved here
| println!("{}",v[0]);
| ^ value used here after move
Isso ocorre porque uma variável ou valor não pode mais ser usado pela função que originalmente possuía uma vez que a propriedade é transferida para outra função.
O que é empréstimo?
Quando uma função transfere seu controle sobre uma variável / valor para outra função temporariamente, por um tempo, isso é chamado de empréstimo. Isso é conseguido passando uma referência para a variável(& var_name)em vez de passar a própria variável / valor para a função. A propriedade da variável / valor é transferida para o proprietário original da variável após a função para a qual o controle foi passado concluir a execução.
fn main(){
// a list of nos
let v = vec![10,20,30];
print_vector(&v); // passing reference
println!("Printing the value from main() v[0]={}",v[0]);
}
fn print_vector(x:&Vec<i32>){
println!("Inside print_vector function {:?}",x);
}
Resultado
Inside print_vector function [10, 20, 30]
Printing the value from main() v[0] = 10
Referências mutáveis
Uma função pode modificar um recurso emprestado usando uma referência mutável a tal recurso. Uma referência mutável é prefixada com&mut. As referências mutáveis podem operar apenas em variáveis mutáveis.
Ilustração: mutando uma referência inteira
fn add_one(e: &mut i32) {
*e+= 1;
}
fn main() {
let mut i = 3;
add_one(&mut i);
println!("{}", i);
}
A função main () declara uma variável inteira mutável i e passa uma referência mutável de i para oadd_one(). O add_one () incrementa o valor da variável i em um.
Ilustração: mutando uma referência de string
fn main() {
let mut name:String = String::from("TutorialsPoint");
display(&mut name);
//pass a mutable reference of name
println!("The value of name after modification is:{}",name);
}
fn display(param_name:&mut String){
println!("param_name value is :{}",param_name);
param_name.push_str(" Rocks");
//Modify the actual string,name
}
A função main () passa uma referência mutável do nome da variável para a função display () . A função de exibição anexa uma string adicional à variável de nome original .
Resultado
param_name value is :TutorialsPoint
The value of name after modification is:TutorialsPoint Rocks