Tipos compuestos

Aunque la semántica de movimiento es la opción predeterminada, algunos tipos se copian de forma predeterminada:

fn main() {
    let x = 42;
    let y = x;
    println!("x: {x}"); // would not be accessible if not Copy
    println!("y: {y}");
}

Estos tipos implementan el trait Copy.

Puedes habilitar tus propios tipos para que usen la semántica de copia:

#[derive(Copy, Clone, Debug)]
struct Point(i32, i32);

fn main() {
    let p1 = Point(3, 4);
    let p2 = p1;
    println!("p1: {p1:?}");
    println!("p2: {p2:?}");
}
  • Después de la asignación, tanto p1 como p2 tienen sus propios datos.
  • También podemos utilizar p1.clone() para copiar los datos de forma explícita.
This slide should take about 5 minutes.

Copiar y clonar no es lo mismo:

  • Copiar hace referencia a las copias bit a bit de regiones de memoria y no funciona en cualquier objeto.
  • Copiar no permite lógica personalizada (a diferencia de los constructores de copias de C++).
  • Clonar es una operación más general y que permite un comportamiento personalizado implementando el trait Clone.
  • Copiar no funciona en los tipos que implementan el trait Drop.

En el ejemplo anterior, prueba lo siguiente:

  • Añade un campo String a struct Point. No se compilará porque String no es de tipo Copy.
  • Remove Copy from the derive attribute. The compiler error is now in the println! for p1.
  • Demuestra que funciona si clonas p1.