Tipos Copiáveis

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}"); // would not be accessible if not Copy
    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 quanto p2 possuem seus próprios dados.
  • Também podemos usar p1.clone() para copiar os dados explicitamente.
This slide should take about 5 minutes.

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 ao struct Point. Ele não irá compilar porque String não é um tipo Copy.
  • Remova Copy do atributo derive. O erro do compilador agora está no println! para p1.
  • Mostre que ele funciona se ao invés disso você clonar p1.

Mais para Explorar

  • Referências compartilhadas são Copy/Clone, referências mutáveis não. Isso porque Rust requer que referências mutáveis sejam exclusivas, então, embora seja válido fazer uma cópia de uma referência compartilhada, criar uma cópia de uma referência mutável violaria as regras de empréstimo do Rust.