Ce problème semble impliquer qu'il ne s'agit que d'un détail d'implémentation ( memcpyvs ???), mais je ne trouve aucune description explicite des différences.
Ce problème semble impliquer qu'il ne s'agit que d'un détail d'implémentation ( memcpyvs ???), mais je ne trouve aucune description explicite des différences.
Réponses:
Cloneest conçu pour les duplications arbitraires: une Cloneimplémentation d'un type Tpeut effectuer des opérations arbitrairement compliquées nécessaires pour créer un nouveau T. 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 Copytrait représente des valeurs qui peuvent être dupliquées en toute sécurité via memcpy: des choses comme les réaffectations et le passage d'un argument par valeur à une fonction sont toujours memcpys, et donc pour les Copytypes, le compilateur comprend qu'il n'a pas besoin de les considérer comme un mouvement .
Cloneune copie profonde et une copie Copymiroir?
Cloneouvre 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- Copytype.
// u8 implements Copy
let x: u8 = 123;
let y = x;
// x can still be used
println!("x={}, y={}", x, y);
// Vec<u8> implements Clone, but not Copy
let v: Vec<u8> = vec![1, 2, 3];
let w = v.clone();
//let w = v // This would *move* the value, rendering v unusable.
À propos, chaque Copytype doit également l'être Clone. 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 a memcpy, pas l' clone(&self)implémentation.
yobtenir un déplacement x, pas une copie, comme avec votre dernier exemple commenté w = v. Comment le préciseriez-vous?
Copyest destiné à être implémenté pour des types "bon marché", comme u8dans 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 impliquer Copy. 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.
Copytrait 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 Copyvs, Clonec'est que cela affecte également la façon dont le compilateur utilise les déplacements par rapport aux copies automatiques. Par exemple:
#[derive(Debug, Clone, Copy)]
pub struct PointCloneAndCopy {
pub x: f64,
}
#[derive(Debug, Clone)]
pub struct PointCloneOnly {
pub x: f64,
}
fn test_copy_and_clone() {
let p1 = PointCloneAndCopy { x: 0. };
let p2 = p1; // because type has `Copy`, it gets copied automatically.
println!("{:?} {:?}", p1, p2);
}
fn test_clone_only() {
let p1 = PointCloneOnly { x: 0. };
let p2 = p1; // because type has no `Copy`, this is a move instead.
println!("{:?} {:?}", p1, p2);
}
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:
error[E0382]: borrow of moved value: `p1`
--> src/lib.rs:20:27
|
18 | let p1 = PointCloneOnly { x: 0. };
| -- move occurs because `p1` has type `PointCloneOnly`, which does not implement the `Copy` trait
19 | let p2 = p1;
| -- value moved here
20 | println!("{:?} {:?}", p1, p2);
| ^^ value borrowed here after move
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.