Bu sorun , bunun yalnızca bir uygulama ayrıntısı ( memcpy
vs ???) 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ı ( memcpy
vs ???) olduğunu ima ediyor gibi görünüyor , ancak farklılıkların açık bir açıklamasını bulamıyorum.
Yanıtlar:
Clone
keyfi çoğaltmalar için tasarlanmıştır: Bir Clone
tür için bir uygulama, T
yeni 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 memcpy
s ve böylece için Copy
türleri, derleyici bu o dikkate almak gerekmez anlar bir hareket .
Clone
Derin kopya ve Copy
gölge kopya olarak anlayabilir miyim ?
Clone
Yazı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, Copy
tü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 Copy
tü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ı memcpy
değil a'yı tetikleyecektir clone(&self)
.
y
taşınmasını istediğinizi varsayalım . Bunu nasıl belirtirsiniz? x
w = v
Copy
gibi "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.Copy
Vs tartışmasında bazen eksik Clone
olan ş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.