---
title: 'Değişkenler ve Değişmezlik'
source: 'https://academia.sh/tr/kurslar/rust-temelleri/degiskenler-ve-degismezlik'
course: 'Rust Temelleri'
language: tr
updated: '2026-09-13T05:09:29+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'let bağlamasının varsayılan olarak değişmez olduğunu ve atamanın kendisinin () ürettiğini gösterir'
    - 'Gölgeleme ile mut ile yeniden atamayı aynı sayısal sonuca ulaşan iki ayrı düzenek olarak karşılaştırır'
    - 'Gölgelemenin bağlamanın tipini değiştirebildiğini, mut ile yeniden atamanın tipi koruduğunu ayırt eder'
---

# Değişkenler ve Değişmezlik

let bir bağlama deyimidir ve atamanın kendisi () üretir; aynı adın üç kez yeniden bağlanması (gölgeleme) ile bir kez bağlanıp iki kez değiştirilmesi (mut) aynı sayısal sonuca ulaşır, ama yalnız gölgeleme aradan tip değiştirebilir — çünkü biri her seferinde yeni bir bağlama kurar, öbürü var olan bağlamanın üzerine yazar.

Giriş noktasının gövdesine artık inilebilir ve gövdenin ilk satırlarının çoğu bir ada bir
değer bağlar (binding). Bu ders bağlamanın kendisini iki açıdan ölçüyor: bağlama işleminin
kendisi bir ifade mi deyim mi ve aynı adı yeniden bağlamanın Rust'ta iki ayrı yolu — biri
her seferinde yepyeni bir bağlama kuran gölgeleme, öbürü var olan bağlamanın üzerine yazan
`mut` — neden aynı sonuca ulaşırken birbirinden bu kadar farklı davranıyor.

Programlama Temelleri kursu (M01/K02) değişken tanımını Python'la kurdu ve gölgelemeyi de
orada tanımladı. Bu kavramlar burada tekrar kurulmaz; bu dersin payı, Rust'ın bağlamayı
**varsayılan olarak değişmez (immutable)** kurması ve gölgelemeye bu değişmezliğin
içinden bir kapı açmasıdır.

Bu sıralama gelişigüzel değil. Önceki ders bir kaynağın çalışabilmesi için gereken en küçük
kümeyi kurdu; bu ders o kümenin içine, giriş noktasının gövdesine iniyor ve orada bir adın
bir değere nasıl bağlandığını soruyor. Sıradaki ders bu bağlanan değerin **hangi tipte**
olabileceğini soracak — ama bir tipin ne olduğunu sormadan önce, bir adın o tipteki değere
nasıl tutunduğunu ve bu tutunmanın ne kadar sıkı olduğunu bilmek gerekiyor. Değişmezlik
işte bu sıkılığın adıdır.

## Bağlama Bir Deyimdir

`let ad = deger;` yazımı iki ayrı parçaya ayrılır. Eşittir işaretinin sağı bir ifadedir —
değerlendirilir ve bir değer üretir. Bütün satır, yani `let` ile başlayan bağlamanın kendisi,
bir deyimdir: hiçbir yerde bir değer olarak kullanılamaz. Bu ayrım küçük görünse de
sonuçları somuttur — bir bağlamayı bir işleve argüman olarak geçiremez, bir listeye
ekleyemez, başka bir ifadenin içine gömemezsin, çünkü elinde `()`ten başka bir şey yoktur.

**RD8.** Rust'ta `let` yalnız gövde düzeyinde durur ve bir ifadenin içine yerleştirilemez;
`(let x = 5)` gibi bir yazım derleyici tarafından kabul edilmez. Bu, `let`in "her zaman bir
deyim" olmasının somut karşılığıdır — istisnası yoktur, hiçbir bağlamda bir değere
dönüşmez. Bunun bir sonucu, kaynağı okuyan tarafın yeni bir adın nerede kurulduğunu tek bir
yerden takip edebilmesidir: her yeni bağlama bir satırın başında, `let` ile açılır; bir
ifadenin ortasında gizlenmiş bir bağlama arama gerekmez.

Atamanın kendisinin de aynı sınıfa girdiğini önceki derste `ifade.rs` çekirdeğinde gördük
("atamanın kendisi" satırı `()` bastı). Burada aynı olguyu, değişkenler konusuna özgü küçük
bir örnekle tekrar koşturalım.

```rust
// deyim_olarak_atama.rs — atamanin kendisi bir deger uretmez
fn main() {
    let mut x = 1;
    println!("x baslangicta: {}", x);
    let atama_sonucu = { x = 9; };
    println!("x simdi: {}", x);
    println!("atamanin kendi degeri: {:?}", atama_sonucu);
}
```

```
x baslangicta: 1
x simdi: 9
atamanin kendi degeri: ()
```

`x = 9` bir ifade olarak değerlendiriliyor — `x`in yeni değeri belleğe yazılıyor — ama bu
ifadenin **kendi değeri** `()`. `atama_sonucu` adlı bağlama bu `()`i tutuyor, `9`u değil.
`x`in yeni değerine ulaşmanın tek yolu `x`in kendisini okumaktır; atamanın sonucunu okumak
hiçbir zaman işe yaramaz, çünkü orada okunacak bir değer yok.

Bu, önceki dersteki bir gözlemi tamamlıyor: `if`, `match`, `loop` ve blok birer değerdir,
ama `let` ve atama birer değer değildir. Aynı dilde hem "bu bir değerdir" hem "bu bir değer
değildir" diyen iki grup yazımın bir arada durması bilinçli bir tercihtir. Bir dallanma ya
da bir döngünün değer üretmesi, o yazımın sonucunun doğrudan bir bağlamaya aktarılmasını
sağlıyor; bir bağlamanın kendisinin değer üretmesi ise anlamsız olurdu, çünkü bağlama zaten
kendisi bir sonuç değil, bir sonucu **saklama** işlemidir. Değer üretmek ile bir yer ayırıp
oraya yazmak, kaynakta iki ayrı eylem olarak kalıyor ve sınıflandırma bu ikisini
karıştırmıyor.

## Gölgeleme ve `mut`: Aynı Sonuç, İki Farklı Yol

Aynı adı yeniden bağlamanın Rust'ta iki yolu var. Biri **gölgeleme (shadowing)**: `let`
anahtar sözcüğü tekrar yazılır ve yepyeni bir bağlama kurulur; eski bağlama artık o adla
erişilemez ama yok olmamıştır. Öbürü `mut`: bağlama bir kez `let mut` ile kurulur, sonraki
satırlar `=` ile doğrudan üzerine yazar; burada yeni bir bağlama yok, var olan bağlamanın
tuttuğu değer değişiyor. İkisini yan yana koşturarak aynı iki adımı (üç ekle, iki ile
çarp) uygulayalım.

```rust
// baglama.rs — golgeleme ile mut arasindaki fark
fn main() {
    // golgeleme: ayni ad uc kez baglaniyor, her biri yeni bir baglama
    let deger = 5;
    let deger = deger + 3;
    let deger = deger * 2;
    println!("golgeleme sonucu: {}", deger);

    // mut: bir kez baglaniyor, iki kez degistiriliyor (ayni baglamaya yazma)
    let mut sayac = 5;
    sayac = sayac + 3;
    sayac = sayac * 2;
    println!("mut sonucu: {}", sayac);

    println!("esit mi: {}", deger == sayac);
}
```

```
golgeleme sonucu: 16
mut sonucu: 16
esit mi: true
```

İki yol da `16`ya ulaşıyor, ama vardıkları yer aynı olsa da oraya gidiş biçimleri farklı.
Gölgelemede üç ayrı `deger` bağlaması var — ikincisi birinciyi okuyup yeni bir bağlama
kuruyor, üçüncüsü ikinciyi okuyup bir yenisini daha kuruyor. `mut` tarafında ise tek bir
`sayac` bağlaması var; iki atama satırı da aynı bağlamanın üzerine yazıyor, yeni bir bağlama
kurmuyor.

Bu iki yolu ayırt eden soru şudur: bir sonraki satır, önceki satırın kurduğu adı mı
**okuyor**, yoksa önceki satırın kurduğu yere mi **yazıyor**? Gölgelemede her `let deger`
satırı önce sağdaki ifadeyi (bir önceki `deger`i kullanarak) değerlendiriyor, sonra bu
sonucu tamamen yeni bir bağlamaya yerleştiriyor — okuma ve yeni bağlama kurma iki ayrı
adımdır. `mut` tarafında okuma ve yazma aynı bağlama üzerinde gerçekleşiyor; `sayac = sayac
+ 3` satırı önce `sayac`ın o anki değerini okuyor, sonra aynı bağlamaya yeni değeri
yazıyor. Sonuç ikisinde de bir toplama ve bir çarpmadır, ama biri adı üç kez yeniden
kullanırken öbürü aynı adı hiç bırakmıyor.

**RD9.** Gölgelemede eski bağlama "silinmiyor", yalnız adıyla erişilemez hâle geliyor. İlk
`deger` (`5`) ile ikinci `deger` (`8`) hâlâ bellekte bir yerde bulunabilir, ama kaynakta
onlara ulaşacak bir ad kalmadı — üçüncü `let deger` ile o ad son bağlamaya taşındı. Bu
davranış K02'nin konusu olan bellek yönetimiyle ilgilidir; burada yalnız gözlemlenen şudur:
gölgeleme adı yeniden kullanıyor, bağlamayı değil.

Gölgelemenin adı yeniden kullanması, önceki dersteki bir başka olguyla birleşiyor: blok
kendisi bir ifadedir ve kendi kapsamını taşır. Bir bloğun içindeki gölgeleme, blok
kapandığında etkisini kaybediyor.

```rust
// golgeleme_kapsam.rs — golgeleme kapsam icinde kalir
fn main() {
    let deger = 10;
    let iceride = {
        let deger = deger * 100;
        deger
    };
    println!("blok icindeki golgeleme: {}", iceride);
    println!("disaridaki deger degismedi: {}", deger);
}
```

```
blok icindeki golgeleme: 1000
disaridaki deger degismedi: 10
```

İç bloktaki `let deger = deger * 100;` dış `deger`i okuyup kendi kapsamında yeni bir
bağlama kuruyor; bu yeni bağlama yalnız bloğun içinde geçerli. Blok kapandığında dış
`deger` hiç dokunulmamış hâliyle geri geliyor — iç bağlama dış bağlamanın üzerine hiçbir
zaman yazmadı, yalnız aynı adı kendi dar kapsamında ödünç aldı. Bu, gölgelemenin `mut`tan
ayrıldığı ikinci nokta: `mut` ile yapılan bir değişiklik kapsam sınırı tanımaz, aynı
bağlamanın olduğu her yerde görünür; gölgeleme ise her `let` ile hem yeni bir bağlama hem de
o bağlamanın kapsamını yeniden kurar.

## Gölgelemenin Tip Değiştirebilmesi

Bu iki yol arasındaki fark yalnız mekanik değil, yetenek farkıdır da. Gölgeleme her seferinde
yepyeni bir bağlama kurduğu için, yeni bağlamanın tipi eskisiyle aynı olmak zorunda değildir.

```rust
// golgeleme_tip.rs — golgeleme ayni adin tipini degistirebilir
fn main() {
    let deger = 21;
    let deger = deger * 2;
    let deger = format!("sonuc={}", deger);
    println!("{}", deger);
}
```

```
sonuc=42
```

İlk `deger` bir tam sayı, üçüncü `deger` bir dizgi (`String`). Üçü de aynı adı taşıyor ama
üçü de birbirinden bağımsız bağlamalar; sonuncusu öncekinin tipini bilmek zorunda değil,
yalnız değerini okuyor ve yeni bir tipte yeni bir bağlama kuruyor.

`mut` ile aynı yazım denenirse derleyici reddeder: `let mut deger = 21` satırından sonra
`deger`e bir dizgi biçimlendirme çağrısının sonucunu atamaya çalışan bir satır derlenmez,
çünkü `mut` yeni bir bağlama kurmuyor, var olan bağlamanın **aynı tipteki** başka bir
değerle değiştirilmesine izin veriyor. Bağlama bir
kez `i32` olarak kurulduktan sonra, o bağlamaya bir `String` yazılamaz — derleyici için bu,
farklı boyuttaki iki değeri aynı yere sığdırmaya çalışmakla eşdeğerdir. Gölgeleme bu kısıtı
taşımıyor, çünkü her `let` derleyiciye "burada yeni bir yer ayır" diyor; `mut` ise "var olan
yere yaz" diyor ve o yerin biçimi ilk `let` ile sabitleniyor.

Bu fark, gölgelemenin neden yalnız bir kısayol olmadığını gösteriyor. Aynı adı taşıyan bir
dizi dönüşüm zincirinde (bir dizgiyi ayrıştırıp bir sayıya, sonra o sayıyı biçimlendirilmiş
bir dizgiye çevirmek gibi) her adımın kendi doğal tipinde kalmasına izin veriyor; okuyan
taraf her adımda hangi tipte olduğunu bağlamanın en son `let` satırından okuyor, ara
adımların tipini takip etmek zorunda kalmıyor. `golgeleme_tip.rs` örneğinde bu zincir üç
adımlıydı: tam sayı olarak başladı, tam sayı olarak katlandı, dizgi olarak biçimlendi. `mut`
ile aynı zincir yazılmak istenseydi, ya üç ayrı ad gerekirdi (`ham_deger`, `katlanmis_deger`,
`bicimli_deger`), ya da her adımın aynı tipte kalması için ekstra bir dönüştürme adımı
eklemek gerekirdi. Gölgeleme bu iki seçeneği de gereksiz kılıyor: tek bir ad, dönüşümün
mantıksal adımlarını izliyor, ama her adımın kendi tipini taşımasına izin veriyor.

Bu yeteneğin bir bedeli de var: aynı adın art arda kaç kez gölgelendiğini takip etmek,
okuyan taraf için `mut`a göre daha fazla dikkat gerektirir. `mut` bir bağlamanın tipini asla
değiştirmediği için, kodun ortasında `sayac`ı gördüğünde tipin ne olduğu ilk `let mut`tan
bellidir. Gölgelemede ise aynı garantiyi vermek için en yakın `let deger` satırına kadar
geriye gitmek gerekir — üç satır önceki `deger` başka bir tip taşıyor olabilir. Kursun
geri kalanında gölgeleme genellikle kısa, birbirine yakın satırlar arasında kullanılacak;
bu yakınlık, tip takibinin okuma sırasında kaybolmamasını sağlıyor.

## Sınırlayıcı Ölçüm: Değişmezlik Bağlamanın Sınırındadır

Önceki iki bölüm değişmezliği hep **tek bir değer** üzerinden gösterdi — bir tam sayı ya
da bir dizgi. Değişmezliğin, birden çok bileşeni bir arada tutan bir değer üzerinde nasıl
davrandığını netleştirmek gerekiyor. `mut` yazılmadan kurulan bir bağlama
yalnız kendi değerini değil, değerin **bütün iç alanlarını** da korur — bir demedin (tuple)
tek bir bileşenini bile ayrıca değiştiremezsin.

```rust
// degismezlik_siniri.rs — baglama degismezken ic alanin durumu
fn main() {
    let nokta = (3, 4);
    println!("baslangic: ({}, {})", nokta.0, nokta.1);

    let nokta2 = (nokta.0 + 1, nokta.1);
    println!("yeni baglama: ({}, {})", nokta2.0, nokta2.1);
    println!("eski baglama degismedi: ({}, {})", nokta.0, nokta.1);
}
```

```
baslangic: (3, 4)
yeni baglama: (4, 4)
eski baglama degismedi: (3, 4)
```

`nokta` hiç `mut` almadan kuruldu. Onu "güncellemek" isteseydik `nokta.0 = 4;` yazmak
gerekirdi — bu satır derlenmez, çünkü `nokta` değişmez bir bağlamadır ve bu değişmezlik
demedin her bileşenine birden uygulanır, yalnız dışarıdan görünen ada değil. Bunun yerine
kod yeni bir bağlama (`nokta2`) kurdu ve eskisinin bileşenlerinden ikisini okuyup üçüncü bir
değeri hesapladı; `nokta` çıktının son satırında görüldüğü gibi hiç değişmedi. Yeni bağlama eskisinin
üzerine değil, eskisinin **yanına** kuruldu; iki bağlama aynı anda, birbirinden bağımsız
olarak var olmaya devam ediyor.

**RD10.** Bu, "değişmezlik derindir" gibi okunabilir ama tam resim değildir. Burada
gösterilen şey, **bir bağlamanın kendisinin** değişmez olduğu — o bağlamaya ait hiçbir
bileşen `mut` olmadan yeniden yazılamaz. Ama aynı verinin **başka bir bağlama ya da
referans üzerinden** paylaşılıp paylaşılamayacağı, paylaşılırsa değişmezliğin oradan da
geçerli olup olmayacağı — bu, sahiplik ve ödünç alma kurallarının sorusudur ve K02'nin
konusudur. Burada çizilen sınır şu: bir bağlamanın `mut` almaması, o bağlamanın kendi adı
üzerinden hiçbir değişikliğe izin vermeyeceğini garanti eder; verinin tamamı hakkında daha
geniş bir garanti değildir.

Bu sınır, önceki iki dersteki sınırlayıcı ölçümlerle aynı ailededir. Rust'ın Tasarım
Hedefleri dersinde bir yöntemin sınıfı çağrı yerine değil imzasına bakılarak belirleniyordu;
Kurulum ve Paket Yöneticisi dersinde bir ikilinin adı kaynağa değil bildirim dosyasına
bakılarak belirleniyordu. Burada da benzer bir kalıp var: bir bağlamanın "ne kadar
değişmez" olduğu, yalnız o bağlamanın kendi bildirimine (`mut` var mı yok mu) bakılarak
belirleniyor — verinin başka yerlerde nasıl paylaşıldığına bakılmadan. Üç ders de aynı
dersi tekrarlıyor: Rust'ta bir garanti okurken, garantinin **nereden** geldiğini bilmek,
garantinin kendisi kadar önemli.

## Özet

- `let ad = deger;` bir deyimdir ve hiçbir yerde bir değer olarak kullanılamaz; sağ taraftaki
  ifade değerlendirilip ada bağlanır.
- Bir atamanın kendisi de `()` üretir; yeni değere ulaşmanın tek yolu adı okumaktır.
- Gölgeleme her `let` ile yepyeni bir bağlama kurar; `mut` ile yeniden atama var olan
  bağlamanın üzerine yazar. İkisi de aynı sayısal sonuca ulaşabilir.
- Yalnız gölgeleme bağlamanın tipini değiştirebilir, çünkü her adımda yeni bir yer ayrılır;
  `mut` bağlamanın ilk tipine bağlı kalır.
- Bir bağlamanın değişmez olması, o bağlamanın bütün iç bileşenlerini kapsar, ama verinin
  başka bir yoldan paylaşılıp paylaşılamayacağı sorusuna yanıt vermez.
- Gölgeleme kapsamla sınırlıdır: bir blok içindeki gölgeleme, blok kapandığında dış
  bağlamayı hiç etkilemeden kaybolur; `mut` ile yapılan değişiklik kapsam tanımaz.

## Sonraki Adım

Bağlamaların taşıdığı değerlerin kendisi henüz tek tek incelenmedi — yalnız tam sayılar
görüldü. Sıradaki ders Rust'ın temel tiplerine iner: tam sayı, kayan noktalı, mantıksal,
karakter ve demet ve her birinin bir ifade olarak ürettiği değerin ne olduğunu, `()`in de
neden bu tiplerden biri sayıldığını koşturarak gösterir. Bu derste kurulan bağlama kavramı
orada değişmeyecek — yalnız bağlanan değerlerin çeşidi genişleyecek ve her tipin kendi
sınırları (bir tam sayının taşabileceği aralık, bir demedin sabit uzunluğu gibi) tek tek
ölçülecek.
