Translate

viernes, 28 de julio de 2023

Copia y Clonación en Rust


Si bien la semántica de movimiento es la predeterminada, ciertos tipos se copian de forma predeterminada:


fn main() {

    let x = 42;

    let y = x;

    println!("x: {x}");

    println!("y: {y}");

}


Estos tipos implementan el rasgo Copy.

Puede optar por que tus propios tipos implementen la semántica de Copy:


#[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 poseen sus propios datos.
  • También podemos usar p1.clone() para copiar explícitamente los datos.


Copiar y clonar no es lo mismo:

  • Copiar se refiere a copias bit a bit de regiones de memoria y no funciona en objetos arbitrarios.
  • La copia no permite una lógica personalizada (a diferencia de los constructores de copias en C++).
  • La clonación es una operación más general y también permite un comportamiento personalizado al implementar el rasgo Clonar.
  • La copia no funciona en los tipos que implementan el rasgo Clone.

En el ejemplo anterior, intente lo siguiente:

  • Agregue un campo de cadena a la estructura Point. No se compilará porque String no es un tipo que implemente copia.
  • Quite Copiar del atributo de derivación. ¡El error del compilador ahora está en el println! para p1.

Derivar es una forma de generar código en Rust en tiempo de compilación. En este caso, se generan las implementaciones predeterminadas de los rasgos Copiar y Clonar.