Clone ve Copy
Coddy'nin Rust Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 37 / 61.
Rust'ta bir değeri another değişkene atadığında, sahiplik genellikle taşınır: özgün değişken geçersiz hâle gelir. Ancak iki standart trait bu davranışı değiştirir: Clone ve Copy.
Copy özelliği örtük bitsel kopyalamayı mümkün kılar. Bir tür Copy uyguladığında, onu başka bir değişkene atamak sahipliği taşımak yerine otomatik bir kopya oluşturur:
#[derive(Copy, Clone)]
struct Point {
x: i32,
y: i32,
}
let p1 = Point { x: 10, y: 20 };
let p2 = p1; // p1 kopyalandı, taşınmadı
println!("{}, {}", p1.x, p2.x); // İkisi de geçerli!
Clone özelliği, .clone() yöntemi aracılığıyla açık derin kopyalama sağlar. Copy türetildiğinde gereklidir, ancak açık kopyalamaya ihtiyaç duyan türler için tek başına da kullanılabilir:
let p3 = p1.clone(); // Açık kopya
Önemli bir kısıtlama vardır: Copy yalnızca tüm alanlarının da Copy uyguladığı türler için türetilebilir. Tamsayılar ve kayan noktalı sayılar gibi basit türler Copy’dir, ancak String değildir. Yığın belleğini yönetir. Yapınız bir String içeriyorsa yalnızca Clone türetebilirsiniz; Copy türetemezsiniz.
| Özellik | Davranış | Kullanım |
|---|---|---|
Copy | Örtük, otomatik | Yalnızca yığında bulunan basit veriler |
Clone | .clone() aracılığıyla açıkça | Kopyalanabilir tüm veriler |
İlkel alanlara sahip basit yapılar için her iki özelliği de türetmek, sahiplik konusunda endişelenmeden değerleri özgürce atamanızı sağlar.
Görev
KolayCopy ve Clone trait'leri arasındaki farkı gösteren bir koordinat sistemi oluşturalım! Biri örtük olarak kopyalanabilen, diğeri ise açıkça klonlama gerektiren iki struct oluşturacak ve Rust'ın türettiğiniz trait'lere bağlı olarak çoğaltmayı nasıl farklı şekilde ele aldığını göreceksin.
Kodunu iki dosyaya ayıracaksın:
coordinates.rs: Farklı koordinat türlerini temsil eden iki public struct tanımla:GridPoint: publicxveyalanlarına sahip (ikisi dei32). Yalnızca ilkel türleri içerdiği için hemCopyhem deClonetüret; böylece atandığında örtük olarak kopyalanabilir.NamedLocation: publicname(String) vex/yalanlarına (i32) sahip. BirStringiçerdiği içinCopydeğil, yalnızcaClonetüretebilirsin. Bu struct'ın çoğaltılması için açıkça.clone()çağrıları gerekecek.
main.rs: coordinates modülünü içeri aktar ve her struct'ın çoğaltıldığında nasıl farklı davrandığını göster. Sağlanan girdileri kullanarak örnekler oluştur, ardından şunları göster:- Bir
GridPoint, başka bir değişkene atanabilir ve her ikisi de geçerli kalır (örtük kopyalama) - Bir
NamedLocation, orijinali geçerli tutarken bir kopya oluşturmak için.clone()kullanmalıdır
- Bir
Çıktın, çoğaltmadan sonra her iki değişkenin de geçerli olduğunu kanıtlamak için hem orijinal hem de kopyalanmış/klonlanmış değerleri göstermelidir:
Original point: ({x}, {y})
Copied point: ({x}, {y})
Original location: {name} at ({x}, {y})
Cloned location: {name} at ({x}, {y})Örneğin, girdiler 5, 10 ve Home olduğunda:
Original point: (5, 10)
Copied point: (5, 10)
Original location: Home at (5, 10)
Cloned location: Home at (5, 10)Üç girdi alacaksın: x koordinatı (i32 olarak ayrıştırılır), y koordinatı (i32 olarak ayrıştırılır) ve konum adı.
Kendin dene
mod coordinates;
use coordinates::{GridPoint, NamedLocation};
fn main() {
// Girdileri oku
let mut input1 = String::new();
std::io::stdin().read_line(&mut input1).expect("Failed to read line");
let x: i32 = input1.trim().parse().expect("Invalid number");
let mut input2 = String::new();
std::io::stdin().read_line(&mut input2).expect("Failed to read line");
let y: i32 = input2.trim().parse().expect("Invalid number");
let mut input3 = String::new();
std::io::stdin().read_line(&mut input3).expect("Failed to read line");
let name = input3.trim().to_string();
// TODO: x ve y ile bir GridPoint örneği oluştur
// TODO: Başka bir değişkene atayarak örtük kopyalamayı göster
// (GridPoint Copy trait'ini uygular, bu yüzden bu otomatik olarak bir kopya oluşturur)
// TODO: Orijinal ve kopyalanmış noktayı yazdır
// Format: "Original point: ({x}, {y})"
// Biçim: "Copied point: ({x}, {y})"
// TODO: name, x ve y ile bir NamedLocation örneği oluştur
// TODO: Açık klonlamayı göster (NamedLocation yalnızca Clone uygular, Copy değil)
// Bir kopya oluşturmak için .clone() kullan
// TODO: Print original and cloned location
// Format: "Original location: {name} at ({x}, {y})"
// Format: "Cloned location: {name} at ({x}, {y})"
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Metotlar ve Davranış
Uygulama Bloklarına GirişSelf ParametresiDeğiştirilebilir Metotlarİlişkili FonksiyonlarBirden Fazla Uygulama BloğuMetot ZincirlemeÖzet - Dikdörtgen Eylemleri4Proje: Sanal Evcil Hayvan
Evcil Hayvanı TanımlamaEvcil Hayvanı Besleme7Standart Trait'ler
Debug Trait'iDisplay Trait'iClone ve CopyEşitlik Trait'leriÖzet - Yazdırılabilir Nokta2Kapsülleme ve Modüller
Modül TemelleriPublic Anahtar KelimesiPrivate AlanlarGetter'larSetter'larÖzet - Güvenli Kasa5Generic Yapılar
Generic Struct'larGeneric MetotlarÇoklu Generic TürlerGeneric FonksiyonlarÖzet - Koordinat Noktası8Sınırlandırıcı Olarak Trait'ler
Trait Sınırlandırıcı SözdizimiÇoklu SınırlandırıcılarWhere CümleciğiTrait'ler ile Tip DöndürmeÖzet - Generic Yazıcı11Rust'ta Tasarım Kalıpları
Newtype KalıbıKompozisyonDrop Trait'iFrom ve IntoÖzet - Smart Pointer Mock3İleri Seviye Enum'lar
Veri İçeren Enum'larEnum MetotlarıVeri Varyantlarını EşlemeOption Enum'ına Yeniden BakışÖzet - Shape Enum6Trait Tanımlama
Trait Nedir?Traitleri UygulamaVarsayılan UygulamalarVarsayılanları Geçersiz KılmaParametreli TraitlerÖzet - Media PlayerKendi başına pratik yap: Online Rust derleyicisi