ProgramlamaRust geliştirici

Rust'ta koleksiyonlar (örneğin, Vec, HashMap) ile nasıl çalışır? Sahiplikleri ile ilgili özellikler nelerdir ve ne zaman elemanları veya koleksiyonu klonlamak gerekir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

Rust'ta standart koleksiyonlar (örneğin Vec<T>, HashMap<K,V>, HashSet<T> vb.) içeriğin sahiplik ilkesini uygular. Bu, koleksiyonun içindeki tüm nesnelere sahip olduğu ve silinmesi durumunda onların belleğini serbest tutmaktan sorumlu olduğu anlamına gelir.

Örneğin, Vec<T>'ye yerleştirilen elemanlar, vektöre taşınır (move) ve vektör artık onlara sahip olur:

let s = String::from("hi"); let mut v = Vec::new(); v.push(s); // s artık taşındı, erişilemez

Eğer koleksiyon kopyalanabilir değerler içeriyorsa, değerler kopyalanır; eğer taşınabilir değerler içeriyorsa, sahiplik hakkı devredilir. Elemanları veya koleksiyonu klonlamak gerektiğinde, orijinal değeri iki yerde saklamak gerektiğindendir, örneğin:

let name = String::from("Olga"); let mut v = Vec::new(); v.push(name.clone()); println!("{}", name); // name hala erişilebilir, çünkü klonlanmıştı

Aldatıcı Soru

Tam olarak taşınabilir bir veri tipi (örneğin, String) anahtar olarak kullanıldığında HashMap'e bir eleman eklediğimizde ne olur? HashMap::insert() içine geçtiğimiz orijinal anahtar erişilebilir olacak mı?

Sıklıkla yanlış cevap verilir: "Orijinal anahtar eklemeden sonra erişilebilir kalacak".

Aslında, anahtarın ve değerin sahipliği HashMap'e devredilir ve ekleme işleminden sonra, önceden klonlamadan onları kullanamazsınız:

let key = String::from("id"); let mut map = std::collections::HashMap::new(); map.insert(key, 42); // key artık erişilemez

key'e erişim denemesi bir derleme hatasına yol açar.

Konunun incelikleri yüzünden yaşanan gerçek hata örnekleri


Hikaye Geliştirici, Vec'e ekledikten sonra taşınmış bir nesneyi kullanmaya çalıştı ve "taşındıktan sonra burada kullanılan değer" hatasını aldı, Vector'un artık ona sahip olduğunu anlamadı.


Hikaye HashMap ile çalışırken string anahtarları klonlamayı unuttuk ve bu, onları başka yerlerde kullanamamamızla sonuçlandı, bu da büyük bir kod yeniden yapılandırmayı gerektirdi.


Hikaye Projelerden birinde, bir işlevin dışında vektörün içsel bir elemanına referans döndürmeye çalıştık, vektörün boyutu değiştiğinde referansın geçersiz olacağını unuttuk. Bu, dangling reference'lara ve çalışma zamanında (panic) çökmesine neden oldu.