Ce problème semble impliquer qu'il ne s'agit que d'un détail d'implémentation ( memcpy
vs ???), mais je ne trouve aucune description explicite des différences.
128
Ce problème semble impliquer qu'il ne s'agit que d'un détail d'implémentation ( memcpy
vs ???), mais je ne trouve aucune description explicite des différences.
Réponses:
Clone
est conçu pour les duplications arbitraires: uneClone
implémentation d'un typeT
peut effectuer des opérations arbitrairement compliquées nécessaires pour créer un nouveauT
. C'est un trait normal (autre que d'être dans le prélude), et nécessite donc d'être utilisé comme un trait normal, avec des appels de méthode, etc.Le
Copy
trait représente des valeurs qui peuvent être dupliquées en toute sécurité viamemcpy
: des choses comme les réaffectations et le passage d'un argument par valeur à une fonction sont toujoursmemcpy
s, et donc pour lesCopy
types, le compilateur comprend qu'il n'a pas besoin de les considérer comme un mouvement .la source
Clone
une copie profonde et une copieCopy
miroir?Clone
ouvre la possibilité que le type puisse faire une copie profonde ou superficielle: "arbitrairement compliqué".La principale différence est que le clonage est explicite. La notation implicite signifie déplacer pour un non-
Copy
type.À propos, chaque
Copy
type doit également l'êtreClone
. Cependant, ils ne sont pas obligés de faire la même chose! Pour vos propres types, cela.clone()
peut être une méthode arbitraire de votre choix, alors que la copie implicite déclenchera toujours amemcpy
, pas l'clone(&self)
implémentation.la source
y
obtenir un déplacementx
, pas une copie, comme avec votre dernier exemple commentéw = v
. Comment le préciseriez-vous?Copy
est destiné à être implémenté pour des types "bon marché", commeu8
dans l'exemple. Si vous écrivez un type assez lourd, pour lequel vous pensez qu'un mouvement est plus efficace qu'une copie, ne le faites pas impliquerCopy
. Notez que dans le cas u8, vous ne pouvez pas être plus efficace avec un mouvement, car sous le capot, cela impliquerait probablement au moins une copie de pointeur - qui est déjà aussi chère qu'une copie u8, alors pourquoi s'embêter.Copy
trait a un impact sur les portées implicites de durée de vie des variables? Si c'est le cas, je pense que c'est remarquable.Comme déjà couvert par d'autres réponses:
Copy
est implicite, peu coûteux et ne peut pas être réimplémenté (memcpy).Clone
est explicite, peut être coûteux et peut être réimplémenté arbitrairement.Ce qui manque parfois dans la discussion de
Copy
vs,Clone
c'est que cela affecte également la façon dont le compilateur utilise les déplacements par rapport aux copies automatiques. Par exemple:Le premier exemple (
PointCloneAndCopy
) fonctionne bien ici à cause de la copie implicite, mais le deuxième exemple (PointCloneOnly
) ferait une erreur avec une utilisation après le déplacement:Pour éviter le déplacement implicite, nous pourrions appeler explicitement
let p2 = p1.clone();
.Cela peut soulever la question de savoir comment forcer un mouvement d'un type qui implémente le trait Copy? . Réponse courte: Vous ne pouvez pas / n'a pas de sens.
la source