Laten we de achtergrond van de kwestie bekijken:
In Rust vereist het concept van geheugenbeheer en eigendom een duidelijke definitie van hoe objecten worden verplaatst en gekopieerd. In de vroege dagen van de taal was het belangrijk om onderscheid te maken tussen eenvoudige byte-kopie (zonder allocaties en logica) en diepe klonen (bijvoorbeeld een kopie van een string, vector). Daarom zijn er twee traits geïntroduceerd — Copy en Clone.
Het probleem is dat niet alle datatypes even goedkoop kunnen worden gekopieerd. Voor sommige structuren is kopiëren gewoon het kopiëren van bits (bijvoorbeeld gehele getallen of tuples van Copy-types), terwijl voor andere (bijvoorbeeld String, Vec) extra werk voor geheugenallocatie nodig is. Het onderscheid tussen Copy en Clone stelt Rust in staat om een compilatiefout te geven als men probeert een ongeldig kopieerproces uit te voeren.
Oplossing:
Copy worden automatisch gekopieerd bij overdracht, toewijzing en overdracht naar functies. Objekten van dergelijke types blijven geldig na het kopiëren.Clone geïmplementeerd, wat een expliciete aanroep van de methode .clone() vereist, vaak met extra geheugenallocatie.Voorbeeldcode:
#[derive(Debug, Copy, Clone)] struct Point { x: i32, y: i32, } fn main() { let p1 = Point { x: 1, y: 2 }; let p2 = p1; // p1 wordt niet "ongeldig" println!("{:?} {:?}", p1, p2); }
Belangrijke kenmerken:
Copy - automatische bitwise kopie, vereist geen handmatige aanroep en beïnvloedt het eigendom niet.Clone - expliciete diepe kopie, geschikt voor structuren met heap-gegevens.Kunnen types met heap-gealloceerde gegevens Copy derivatie hebben?
Nee, types die heap-gegevens bevatten (zoals String, Vec) kunnen Copy niet automatisch implementeren, omdat dit tot dubbele vrijgave van geheugen zou leiden.
Als een type Copy implementeert, kan het dan ook handmatig Clone implementeren met andere logica?
Ja, Clone kan handmatig worden geïmplementeerd en de logica kan verschillen, echter wordt aangeraden dat Copy en Clone consistent zijn: Copy roept gewoon Clone aan zonder allocaties.
#[derive(Copy)] struct X; impl Clone for X { fn clone(&self) -> X { *self } }
Als een structuur alleen Copy-velden bevat, maar niet is gemarkeerd met #[derive(Copy)], zal het dan Copy zijn?
Nee, een type wordt niet automatisch Copy vanwege zijn samenstelling — expliciete Copy derivatie is vereist voor je type.
Een type met heap-gegevens is foutief gemarkeerd als Copy, er vindt dubbele vrijgave van geheugen plaats tijdens de finalisatie.
Voordelen:
Nadelen:
Gebruik Copy voor lichte structuren (coördinaten, kleuren), Clone — voor complexe (strings, vectoren). De code is veilig en voorspelbaar.
Voordelen:
Nadelen: