Rust, Rust kitabını sunmasına rağmen mut
anahtar kelimesini anlamakta zorlandım. Kendime "Bu sorunu yaşayan tek kişi ben miyim?" diye sordum. Hızlı bir Google araması yalnız olmadığımı doğruladı.
Sonuç olarak mut
anahtar kelimesinin detaylı açıklamasını sunmak amacıyla bu yazıyı yazmaya karar verdim. Bu makale Python veya JavaScript gibi üst düzey dillerden gelenlere yöneliktir.
Rust'ta değiştirilemeyen bir değişken oluşturmak için basitçe yazmanız yeterlidir let x = 1337
. Çok basit. Daha sonra değiştirilebilecek bir değişken oluşturmak istiyorsanız, mut
anahtar sözcüğünü let
sonra eklemeniz yeterlidir. Rust'ın niyetlerin netliğini teşvik eden yararlı bir geleneği var.
mut
anahtar sözcüğünün eklenmesi, başkalarına bu değişkenin kodun başka bir yerinde değiştirileceğini bildirir. Tamam aşkım.
Hadi görselleştirelim. Burada iki değişken var, let mut x = 1337
ve let y = 42
.
Şu anda her şey basit. Ancak mut
referanslarını kullanırken işler biraz karışmaya başlar. Biraz oluşturalım.
let mut x = 1337; let y = 42; let x_ref = &mut x; let y_ref = &y;
İki referans oluşturdum (veya Rust açısından "ödünç aldım"). Bunlardan biri değiştirilebilir bir referans, diğeri ise salt okunur bir referanstır. Bunun için yine bir şema oluşturalım.
Verilen şemada 2'si referans olan 4 değişkenim var. Her iki referans değişkeni de değişmezdir ve let
sonra mut
anahtar sözcüğüne sahip değildir; bu, onların işaret ettiği şeyi değiştiremeyeceğim anlamına gelir. Ancak yine de referans verdikleri değeri değiştirebilirim.
*x_ref = 777;
Bunu yazarsanız Rust derleyicisi şikayet etmeyecek ve x
değeri (ref'in kendisi değil) 777
olarak değişecektir. Ancak şemada x_ref
değişkenlik seçeneğinden yoksun olduğunu gösteren kırmızı bir kare var. Peki neden atıfta bulunduğu değeri değiştirebilirim?
Let let x_ref = &mut x
şemasına geri dönelim.
İlk beyaz blok şu adı içerir: x_ref
. İkincisi bana o değişkende saklanan tür hakkında bilgi veriyor. Tam haliyle, herhangi bir örtülü tür açıklaması olmadan aşağıdaki gibi yazabilirim:
let x_ref: &mut i32 = &mut x;
Bunu şu şekilde yorumlayabilirim: x_ref
adında, i32
değiştirilebilir bir referans tutacak ve bunu x
değişkenindeki i32
değerine değiştirilebilir referansla hemen başlatacak değişmez bir değişken oluşturalım.
Bu, işaret ettiği değeri değiştirebileceğim ancak referansın değerini (veya adresini) değiştiremeyeceğim anlamına gelir. Başka bir deyişle, şöyle bir şey yazamam:
let x_ref: &mut i32 = &mut x; let mut z = 0; x_ref = &mut z; // Not allowed!
Şemalar açısından yukarıdaki kod bloğunda okun gösterdiği yönü değiştirmek istiyorum. Ancak z
değişkeni değiştirilebilir olsa bile oku değiştiremiyorum çünkü sorun x_ref
değişmezliğinde yatıyor.
Ok yönünü değiştirmek için x_ref
değişkeninde saklanan adresi değiştirmem gerekiyor. Ancak değişken değişmez olduğundan bunu yapamam.
Hadi yapalım!
let mut x: i32 = 1337; let mut x_ref: &mut i32 = &mut x; // I've added mut before x_ref let mut z = 0; x_ref = &mut z; // Allowed!
Burada x_ref
çevresinde çok fazla mut
örneği var, değil mi? Bunları anlatalım.
let mut x_ref
: x_ref
adında değiştirilebilir bir değişken oluşturuyorum, bu da değerini daha sonra değiştirebileceğim anlamına geliyor.
&mut i32
: Değişkenin i32
tipindeki bazı değerlere değişken referans(lar) içereceğini belirtiyorum.
&mut x
: x
değişkenini ödünç alıyorum (referans alıyorum).
Daha sonra z
adında bir değişken oluşturdum ve ona 0
değerini atadım. Daha sonra x_ref = &mut z
yazdığımda x_ref
yalnızca i32
değerlerine referans tutabilen değişken bir değişken olduğunu anladığımı belirttim.
z
tipi i32
olduğundan adresini x_ref
değişkenine atayabiliyorum. z
adresini elde etmek için &mut z
sözdizimini kullandım.
Şema.
İfadedeki =
öğesine bir göz atın, biraz açık görünebilir, ancak…
let mut x_ref = &mut x;
… Bunu, ifadeyi iki alt ifadeye bölen bir bölücü olarak görüyorum (özellikle 90 derece döndürürseniz): sol ve sağ. Sol taraf değişkenin kendisi hakkında bilgi verirken sağ taraf bize değer hakkında bilgi verir.
Değeri değiştirmek için *
referans operatörünü kullandığımda...
*x_ref = 100;
... x_ref
değişkeninin değerini değiştirmiyorum. Bunun yerine x_ref
referans aldığı değeri değiştiriyorum.
Daha önce mut
sık sık kullanıyordum. Peki ya bazılarını atlarsam?
let i = 1; let j = 2; let mut k = &i;
Burada i
değerini değiştirebilir miyim? Bölücü tekniğini kullanarak cevaplamak oldukça basittir. k
değerini değiştirebilirim (sol tarafta mut
görüyorum), ancak değer (sağ tarafta) i
değişmez bir referanstır (burada mut
yok).
Öyleyse…
let i = 1; let j = 2; let mut k = &i; k = &j; // This is legal. *k = 3; // This is not.
Şema.
Bu makalede mut
anahtar sözcüğünün ve referanslarının nüanslarını inceledik. Değişken bir referans ile referansı tutan değişken bir değişken arasında bir ayrım olduğunu unutmayın. Bizim numaramız mı?
Rust'taki ödevleri daha iyi anlamak için =
işaretini zihinsel ayırıcı olarak kullanmak. Bu basit görselleştirme birçok karışıklığı ortadan kaldırabilir.
Mutlu kodlama!