Emprestando um Valor
Como vimos antes, ao invĂ©s de transferir a ownership ao chamar uma função, vocĂȘ pode deixar uma função emprestar (borrow) o valor:
#[derive(Debug)] struct Point(i32, i32); fn add(p1: &Point, p2: &Point) -> Point { Point(p1.0 + p2.0, p1.1 + p2.1) } fn main() { let p1 = Point(3, 4); let p2 = Point(10, 20); let p3 = add(&p1, &p2); println!("{p1:?} + {p2:?} = {p3:?}"); }
- A função
add
pega emprestado (borrows) dois pontos e retorna um novo ponto. - O chamador mantém a ownership das entradas.
Este slide Ă© uma revisĂŁo do material sobre referĂȘncias do dia 1, expandindo um pouco para incluir argumentos e valores de retorno de funçÔes.
Mais para Explorar
Notas sobre os retornos da pilha:
-
Demonstrate that the return from
add
is cheap because the compiler can eliminate the copy operation. Change the above code to print stack addresses and run it on the Playground or look at the assembly in Godbolt. In the âDEBUGâ optimization level, the addresses should change, while they stay the same when changing to the âRELEASEâ setting:#[derive(Debug)] struct Point(i32, i32); fn add(p1: &Point, p2: &Point) -> Point { let p = Point(p1.0 + p2.0, p1.1 + p2.1); println!("&p.0: {:p}", &p.0); p } pub fn main() { let p1 = Point(3, 4); let p2 = Point(10, 20); let p3 = add(&p1, &p2); println!("&p3.0: {:p}", &p3.0); println!("{p1:?} + {p2:?} = {p3:?}"); }
-
O compilador Rust pode fazer otimização de valor de retorno (Return Value Operation - RVO).
-
Em C++, a elisão (omissão) de cópia deve ser definida na especificação da linguagem porque os construtores podem ter efeitos colaterais. Em Rust, isso não é um problema. Se o RVO não aconteceu, o Rust sempre executarå uma cópia
memcpy
simples e eficiente.