इस समस्या का अर्थ यह है कि यह केवल एक कार्यान्वयन विवरण है ( memcpy
बनाम ???), लेकिन मुझे मतभेदों का कोई स्पष्ट विवरण नहीं मिल सकता है।
इस समस्या का अर्थ यह है कि यह केवल एक कार्यान्वयन विवरण है ( memcpy
बनाम ???), लेकिन मुझे मतभेदों का कोई स्पष्ट विवरण नहीं मिल सकता है।
जवाबों:
Clone
को मनमाने ढंग से दोहराव के लिए डिज़ाइन किया गया है: एक Clone
प्रकार के लिए एक कार्यान्वयन T
एक नया बनाने के लिए आवश्यक रूप से जटिल परिचालन कर सकता है T
। यह एक सामान्य लक्षण है (प्रस्तावना में होने के अलावा), और इसलिए सामान्य कॉल की तरह, कॉल आदि के साथ इसका उपयोग करने की आवश्यकता होती है।
Copy
विशेषता मान जो सुरक्षित रूप से के माध्यम से दोहराया जा सकता है का प्रतिनिधित्व करता है memcpy
: reassignments कर रहे हैं और एक कार्य करने के लिए दर-मूल्य एक तर्क गुजर हमेशा की तरह बातें memcpy
है, और इतने के लिए Copy
प्रकार, संकलक समझता है कि यह उन पर विचार करने की जरूरत नहीं है एक चाल ।
Clone
एक गहरी-प्रति है, और Copy
छाया-प्रति है?
Clone
इस संभावना को खोलता है कि प्रकार या तो गहरी या उथली प्रतिलिपि कर सकता है: "मनमाने ढंग से जटिल"।
मुख्य अंतर यह है कि क्लोनिंग स्पष्ट है। अव्यय संकेतन का अर्थ है गैर- Copy
प्रकार के लिए चलना ।
// 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.
वैसे, हर Copy
प्रकार का होना भी आवश्यक है Clone
। हालांकि, उन्हें एक ही काम करने की आवश्यकता नहीं है! अपने स्वयं के प्रकारों के लिए, .clone()
अपनी पसंद का एक मनमाना तरीका हो सकता है, जबकि अंतर्निहित नकल हमेशा एक ट्रिगर होगी memcpy
, clone(&self)
कार्यान्वयन नहीं ।
y
एक स्थानांतरित करना चाहते हैं x
, इसकी एक प्रति नहीं है, जैसे कि आपके अंतिम उदाहरण के साथ w = v
। आप इसे कैसे निर्दिष्ट करेंगे?
Copy
"सस्ते" प्रकारों के लिए लागू किया जाना है, जैसे u8
कि उदाहरण में। यदि आप एक बहुत भारी वजन लिखते हैं, जिसके लिए आपको लगता है कि एक प्रतिलिपि की तुलना में एक चाल अधिक कुशल है, तो इसे निहित न करेंCopy
। ध्यान दें कि u8 के मामले में, आप संभवतः एक चाल के साथ अधिक कुशल नहीं हो सकते हैं, क्योंकि हुड के तहत यह संभवतः कम से कम एक पॉइंटर कॉपी में प्रवेश करेगा - जो पहले से ही u8 कॉपी के रूप में महंगा है, इसलिए परेशान क्यों है।
Copy
चर की उपस्थिति का वैरिएबल के अंतर्निहित आजीवन दायरे पर प्रभाव पड़ता है? यदि ऐसा है तो मुझे लगता है कि यह उल्लेखनीय है।
जैसा कि पहले से ही अन्य उत्तरों द्वारा कवर किया गया है:
Copy
निहित है, सस्ती है, और फिर से लागू नहीं किया जा सकता (मेमसीपी)।Clone
स्पष्ट है, महंगा हो सकता है, और मनमाने ढंग से फिर से लागू हो सकता है।कभी-कभी Copy
बनाम की चर्चा में जो चीज गायब होती Clone
है, वह यह भी प्रभावित करती है कि कंपाइलर बनाम स्वचालित प्रतियों का उपयोग कैसे करता है। उदाहरण के लिए:
#[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);
}
पहला उदाहरण ( PointCloneAndCopy
) यहाँ अंतर्निहित प्रतिलिपि के कारण ठीक काम करता है, लेकिन दूसरा उदाहरण ( PointCloneOnly
) इस कदम के बाद उपयोग के साथ त्रुटि करेगा:
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
निहित कदम से बचने के लिए, हम स्पष्ट रूप से कॉल कर सकते हैं let p2 = p1.clone();
।
यह प्रश्न उठा सकता है कि एक प्रकार की चाल को कैसे लागू किया जाए जो प्रतिलिपि विशेषता को लागू करता है? । संक्षिप्त उत्तर: आप समझ नहीं सकते / नहीं बना सकते।