Este problema parece implicar que es solo un detalle de implementación ( memcpy
vs ???), pero no puedo encontrar ninguna descripción explícita de las diferencias.
128
Este problema parece implicar que es solo un detalle de implementación ( memcpy
vs ???), pero no puedo encontrar ninguna descripción explícita de las diferencias.
Respuestas:
Clone
está diseñado para duplicaciones arbitrarias: unaClone
implementación para un tipoT
puede realizar operaciones arbitrariamente complicadas necesarias para crear un nuevoT
. Es un rasgo normal (aparte de estar en el preludio), por lo que requiere que se use como un rasgo normal, con llamadas a métodos, etc.El
Copy
rasgo representa valores que se pueden duplicar de forma segura a través dememcpy
: cosas como reasignaciones y pasar un valor por argumento a una función son siemprememcpy
s, por lo que para losCopy
tipos, el compilador comprende que no necesita considerarlos como un movimiento .fuente
Clone
es una copia profunda yCopy
es una instantánea?Clone
abre la posibilidad de que el tipo pueda hacer una copia profunda o superficial: "arbitrariamente complicado".La principal diferencia es que la clonación es explícita. La notación implícita significa mover para un no
Copy
tipo.Por cierto, todos los
Copy
tipos también deben serloClone
. Sin embargo, ¡no están obligados a hacer lo mismo! Para sus propios tipos,.clone()
puede ser un método arbitrario de su elección, mientras que la copia implícita siempre activará amemcpy
, no laclone(&self)
implementación.fuente
y
moverx
, no una copia, como con su último ejemplo comentadow = v
. ¿Cómo especificarías eso?Copy
está destinado a implementarse para tipos "baratos", comou8
en el ejemplo. Si escribe un tipo bastante pesado, para el que cree que un movimiento es más eficiente que una copia, no lo haga implícitoCopy
. Tenga en cuenta que en el caso de u8, posiblemente no puede ser más eficiente con un movimiento, ya que bajo el capó probablemente al menos implicaría una copia de puntero, que ya es tan cara como una copia de u8, así que ¿para qué molestarse?Copy
rasgo tiene un impacto en los alcances de vida implícitos de las variables? Si es así, creo que es digno de mención.Como ya se cubrió en otras respuestas:
Copy
es implícito, económico y no se puede volver a implementar (memcpy).Clone
es explícito, puede ser caro y puede volver a implementarse arbitrariamente.Lo que a veces falta en la discusión de
Copy
vsClone
es que también afecta cómo el compilador usa movimientos vs copias automáticas. Por ejemplo:El primer ejemplo (
PointCloneAndCopy
) funciona bien aquí debido a la copia implícita, pero el segundo ejemplo (PointCloneOnly
) produciría un error con un uso después de mover:Para evitar el movimiento implícito, podríamos llamar explícitamente
let p2 = p1.clone();
.Esto puede plantear la pregunta de cómo forzar un movimiento de un tipo que implemente el rasgo Copiar. . Respuesta corta: no puede / no tiene sentido.
fuente