Hareket vs Pas Kopyala
Hadi bu yapı var
struct Triplet {
one: int,
two: int,
three: int,
}
Eğer bir fonksiyon için bu sınavı geçersem, örtülü olarakkopyalanan. Şimdi bazen bazı değerler olmadığını okudumcopyableve bu nedenle varhareket ettirinyerine. struct Triplet
bu sigara yapmak için, mümkün olur muydu merak ediyorumcopyablenedense? Bu olacak pas söyleyen bazı ekstra özellik uygulamak gibiolmayan copyableve bu nedenle vardırhareket ettirinyerine.
Bir örtülü olmayan şeyler kopyalamak için Clone
özellik uygulamak için her yerde okudumcopyableama ben asla böyle bir şey olması da tam tersiörtülü olarakcopyableve bunu yapmaolmayan copyableo kadartaşıryerine.
O bile mantıklı geliyor mu?
CEVAP
ÖnsözBu cevap opt-in built-in traits - önce yazıldı;özellikle the Copy
aspects - uygulanmıştır. Blok tırnak sadece eski düzeni için uygulanan bölüm (soru sorulduğu zaman uygulanan bir) belirtmek için kullandım.
Eski: Temel soruyu cevaplamak için, bir işaretleyici alan
NoCopy
value bir depolama ekleyebilirsiniz. E. g.struct Triplet { one: int, two: int, three: int, _marker: NoCopy }
Ayrıca bir yıkıcı (
Drop
trait uygulama üzerinden) alarak yapabilirsin, ama marker türleri kullanarak yıkıcı bir şey yapıyorsa tercih edilir.
Türleri artık sizin türü için açıkça bunu uygulamak sürece Copy
uygulamak değil yeni tanımlarken varsayılan olarak, bu hareket,:
struct Triplet {
one: i32,
two: i32,
three: i32
}
impl Copy for Triplet {} // add this for copy, leave it out for move
Bu uygulama sadece her tür yeni struct
enum
içerdiği kendisi Copy
ise var olabilir. Derleyici hata iletisi yazdırır. Ayrıca sadece yazın varyokDrop
bir uygulama var.
Bu soruya cevap vermek istemedin... "ne hareketler oldu ve anlaşıldı mı?":
Öncelikle iki farklı tarif edeceğim "kopya":
- birbayt kopyalayınolan sadece sığ kopyalama bir nesneyi byte-by-byte, aşağıdaki işaretçiler, örneğin varsa
(&uint, u64)
16 bayt üzerinde bir 64-bit bilgisayar ve sığ bir kopya olur alarak bu 16 bayt ve çoğaltma onların değeri başka bir 16-bayt yığın bellekolmadan&
diğer ucundauint
dokunaklı. Yani,memcpy
arama için eşdeğer. - birsemantik kopyalayıngüvenli bir şekilde ayrı olarak eski için kullanılabilir (biraz) yeni bağımsız bir örneğini oluşturmak için bir değeri çoğaltarak. E. g. bir anlam kopyası
Rc<T>
içerir sadece artan başvuru sayısı ve anlamsal bir kopyasınıVec<T>
içerir oluşturma Yeni bir ayırma ve sonra da anlamsal kopyalama her saklı elementler eski yeni. Bu olabilir derin kopyalarını (örneğinVec<T>
) veya sığ (örneğinRc<T>
dokunmaz saklıT
),Clone
gevşek bir tanım olarak küçük miktarda iş için gerekli anlamsal kopya bir değer türüT
içinden&T
T
.
Pas gibi Cher-değeri bir baytlık bir kopyası vardır:
let x: T = ...;
let y: T = x; // byte copy
fn foo(z: T) -> T {
return z // byte copy
}
foo(y) // byte copy
Ya T
hamle olup olmadığını bayt sayfa "örtülü copyable". (Açık olmak gerekirse, mutlaka tam zamanında byte-by-byte kopyasını değil mi: derleyici kodu davranışları korunur.) Eğer kopya optimize etmek için ücretsiz.
Ancak, bayt kopya ile temel bir sorun var: eğer yıkıcı, örn . eğer çok kötü olabilir Bellek yinelenen değerleri ile sona
{
let v: Vec<u8> = vec![1, 2, 3];
let w: Vec<u8> = v;
} // destructors run here
Eğer w
sadece düz bayt kopyalama v
sonra orada olacağını gösteren iki vektör de aynı ayırma, hem de yıkıcı olan ücretsiz... neden a double free olan bir sorun. NB. Bunun gayet iyi, eğer yaptığımız bir anlam kopyalama v
w
beri w
olurdu kendi bağımsız Vec<u8>
ve yıkıcı olmazdı ayaklar altına birbirimizi.
Birkaç olası düzeltmeler var:
- Programcı kolu, (o kadar kötü değil yani C yıkıcılar var, hayır... sadece bellek sızıntısı ile yerine. sol C. gibi yapalım :P )
- Semantik bir kopyasını
w
kendi ayırma, böylece dolaylı olarak, kopyalama ve varsayılan C gibi gerçekleştirin. - Nezdinde değer
v
artık kullanılabilir ve yıkıcı çalışma yok, böylece mülkiyet gibi bir aktarım kullanır.
Son Pas yapıyorhareket ettirinkaynak statik olarak nerede olduğunu sadece tarafından değer kullanılır derleyici artık geçersiz bellek daha fazla kullanımı önler bu yüzden geçersiz.
let v: Vec<u8> = vec![1, 2, 3];
let w: Vec<u8> = v;
println!("{}", v); // error: use of moved value
Türleri yıkıcılargerekirhareket ederken kullanılan değer (aka zaman kopyalanan bayt), beri var yönetimi/mülkiyet bazı kaynak (örneğin, bir bellek ayırma veya bir dosya tanıtıcı) ve onun çok olası bir bayt kopyalar doğru yinelenen bu sahiplik.
"...Örtülü bir kopyası nedir?"
u8
gibi ilkel bir tip düşünün: bir bayt kopyalama basit, sadece tek bayt kopyalama ve semantik bir kopyası gibi basit, tek bayt kopyalayın. Özellikle, bir bayt kopyalayınsemantik bir kopyasını... Pas bile anlamsal ve bayt aynı kopya olan yakalar built-in trait Copy
vardır.
Dolayısıyla, Copy
bu tür tarafından değeri kullanır güvende kaynağını kullanmaya devam etmek, bu yüzden de otomatik olarak semantik kopyalarıdır.
let v: u8 = 1;
let w: u8 = v;
println!("{}", v); // perfectly fine
Eski:
NoCopy
işaretleyiciCopy
(ilkel tek içeren toplamları ve&
gibi) olabilir türleriCopy
olduğunu varsayarak derleyici otomatik davranışı geçersiz kılar. Ancak bu opt-in built-in traits uygulandığında değişen olacaktır.
Yukarıda da belirtildiği gibi, opt-in built-in özellikleri uygulanır, derleyici artık otomatik davranış vardır. Ancak, bu kural geçmişte otomatik davranışlar için kullanılan yasal Copy
uygulamak için olup olmadığını kontrol etmek için aynı kurallar.
Objective C - Ata, Kopyala, Koru...
Böyle büyük mükafat/iOS5: Hareket klav...
Nasıl özel hareket hızı oluşturma Teme...
Resim ile üstteki kopyala/yapıştır...
Kopyala / FireFox, Safari ve Chrome il...