Bu sorun , bunun yalnızca bir uygulama ayrıntısı ( memcpyvs ???) olduğunu ima ediyor gibi görünüyor , ancak farklılıkların açık bir açıklamasını bulamıyorum.
Bu sorun , bunun yalnızca bir uygulama ayrıntısı ( memcpyvs ???) olduğunu ima ediyor gibi görünüyor , ancak farklılıkların açık bir açıklamasını bulamıyorum.
Yanıtlar:
Clonekeyfi çoğaltmalar için tasarlanmıştır: Bir Clonetür için bir uygulama, Tyeni bir T. Bu normal bir özelliktir (başlangıçta olmaktan başka) ve bu nedenle normal bir özellik gibi, yöntem çağrılarıyla vb. Kullanılmasını gerektirir.
CopyÖzellik güvenle yoluyla kopyalanabilir değerleri temsil memcpy: dönüşlerinde ve her zaman bir işleve by-değeri bir argüman vardır geçirerek gibi şeyler memcpys ve böylece için Copytürleri, derleyici bu o dikkate almak gerekmez anlar bir hareket .
CloneDerin kopya ve Copygölge kopya olarak anlayabilir miyim ?
CloneYazının derin ya da yüzeysel bir kopya yapma olasılığını açar : "keyfi olarak karmaşık".
Temel fark, klonlamanın açık olmasıdır. Örtülü gösterim, Copytür olmayan için hareket anlamına gelir .
// 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.
Bu arada her Copytürün de olması gerekiyor Clone. Ancak aynı şeyi yapmak zorunda değiller! Kendi türleriniz için, .clone()seçtiğiniz keyfi bir yöntem olabilir, oysa örtük kopyalama her zaman uygulamayı memcpydeğil a'yı tetikleyecektir clone(&self).
ytaşınmasını istediğinizi varsayalım . Bunu nasıl belirtirsiniz? xw = v
Copygibi "ucuz" tipler için uygulanmalıdır u8. Eğer bir hareket bir kopyasını daha etkilidir düşündüğümüz için oldukça ağır tip, yazarsanız, bunu yapmak değil impl Copy. U8 durumunda, bir hareketle daha verimli olamayacağınıza dikkat edin, çünkü kaputun altında muhtemelen en azından bir işaretçi kopyası gerektirecektir - ki bu zaten bir u8 kopyası kadar pahalıdır, öyleyse neden zahmet etmelisiniz.
Copyözelliğin varlığının değişkenlerin örtük yaşam süresi kapsamları üzerinde bir etkisi olduğu anlamına mı geliyor ? Öyleyse bunun dikkate değer olduğunu düşünüyorum.
Zaten diğer yanıtların kapsadığı gibi:
Copy örtüktür, ucuzdur ve yeniden uygulanamaz (memcpy).Clone açıktır, pahalı olabilir ve keyfi olarak yeniden uygulanabilir.CopyVs tartışmasında bazen eksik Cloneolan şey, derleyicinin hamle ve otomatik kopyaları nasıl kullandığını da etkilemesidir. Örneğin:
#[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);
}
İlk örnek ( PointCloneAndCopy) örtük kopya nedeniyle burada iyi çalışıyor, ancak ikinci örnek ( PointCloneOnly) taşıma sonrası kullanımda hata veriyor:
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
Örtük hareketten kaçınmak için açıkça arayabiliriz let p2 = p1.clone();.
Bu , Kopyalama özelliğini uygulayan türde bir hareketin nasıl zorlanacağı sorusunu gündeme getirebilir. . Kısa cevap: Mantıklı değilsin / değil.