Copia e Clonagem
Embora a semântica de movimento seja o padrão, certos tipos são copiados por padrão:
fn main() { let x = 42; let y = x; println!("x: {x}"); println!("y: {y}"); }
Esses tipos implementam o trait Copy
.
Você pode habilitar seus próprios tipos para usar a semântica de cópia:
#[derive(Copy, Clone, Debug)] struct Point(i32, i32); fn main() { let p1 = Point(3, 4); let p2 = p1; println!("p1: {p1:?}"); println!("p2: {p2:?}"); }
- Após a atribuição, tanto
p1
quantop2
possuem seus próprios dados. - Também podemos usar
p1.clone()
para copiar os dados explicitamente.
Copia e clonagem não são a mesma coisa:
- Cópia refere-se a cópias bit a bit de regiões de memória e não funciona em objetos arbitrários.
- Cópia não permite lógica personalizada (ao contrário dos construtores de cópia em C++).
- Clonagem é uma operação mais geral e também permite um comportamento personalizado através da implementação do trait
Clone
. - Cópia não funciona em tipos que implementam o trait
Drop
.
No exemplo acima, tente o seguinte:
- Adicione um campo
String
aostruct Point
. Ele não irá compilar porqueString
não é um tipoCopy
. - Remova
Copy
do atributoderive
. O erro do compilador agora está noprintln!
parap1
. - Mostre que ele funciona se ao invés disso você clonar
p1
.
Se os alunos perguntarem sobre derive
, basta dizer que isto é uma forma de gerar código em Rust em tempo de compilação. Nesse caso, as implementações padrão dos traits Copy
e Clone
são geradas.