---
title: Numaralandırmalar
source: 'https://academia.sh/tr/kurslar/swift/numaralandirmalar'
course: 'Swift Dili'
language: tr
updated: '2026-10-21T05:03:12+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Ham değerli numaralandırmanın rawValue ve rawValue ile kurma yollarını ölçer'
    - 'İlişkili değerin durum kurulurken bir kez değerlendirildiğini gösterir'
    - 'switch ile desen eşlemenin ilişkili değeri bir ada bağladığını çıktıdan okur'
    - 'Numaralandırmadaki hesaplanan özelliğin her okunuşta yeniden koştuğunu ölçer'
---

# Numaralandırmalar

Ham değerin ve ilişkili değerin ne zaman kurulduğunun, desen eşlemeyle nasıl açıldığının ve hesaplanan özelliğin her okunuşta koştuğunun ölçümü.

Önceki ders alan listesi olan tipleri ölçtü: yapı ve sınıf, hep aynı alanları taşır. Bazı veriler ise bir alan listesi değil, birkaç ayrı durumdan birinde olmayı gerektirir. Haftanın günü yedi değerden biridir; bir ölçüm ya derece cinsinden bir sayıdır ya da bir etikettir. Bu iki örnek farklı şeyleri anlatır, ama ikisi de **numaralandırma (enumeration)** ile ifade edilir.

Swift numaralandırması birçok dildeki karşılığından daha güçlüdür. Her durum (`case`) yalnızca bir ad değildir; tanımına göre bir **ham değer (raw value)** ya da durumla birlikte taşınan bir **ilişkili değer (associated value)** olabilir. Numaralandırmalar ayrıca hesaplanan özellik ve yöntem taşıyabilir; saklanan örnek özelliği taşıyamaz. Ders önce bu iki değer çeşidinin ne zaman kurulduğunu, sonra bir numaralandırma içindeki hesaplamanın ne zaman koştuğunu ölçer. Kursun ölçü ekseni değişmez: **bu ifade ne zaman değerlendiriliyor?** Dört an vardır: hemen, ilk kullanımda, her kullanımda, hiç. `Probe` sınıfı aşağıda olduğu gibi verilir.

## Çekirdek

Her ders aynı çekirdeği kullanır. `Probe` bir ifadenin kaç kez değerlendirildiğini (`eval`) ve kaç kez kullanıldığını (`use`) sayar; `moment` özelliği bu iki sayıdan anı çıkarır. Açılış dersindeki bağlayıcı ölçümde sekiz ifadenin dağılımı 2/1/3/2 idi: ikisi hemen, biri ilk kullanımda, üçü her kullanımda, ikisi hiç. Bu derste yalnız kendi kesitini ölçeriz.

```swift
// Probe.swift — bir ifadenin ne zaman degerlendirildigini kaydeder
final class Probe {
    let label: String
    private(set) var evaluations = 0
    private(set) var uses = 0
    private var evaluatedBeforeUse = false

    init(_ label: String) {
        self.label = label
    }

    func eval<T>(_ value: T) -> T {
        evaluations += 1
        if uses == 0 { evaluatedBeforeUse = true }
        return value
    }

    func use<T>(_ access: () -> T) -> T {
        uses += 1
        return access()
    }

    var moment: String {
        if evaluations == 0 { return "hic" }
        if evaluations > 1 { return "her-kullanimda" }
        return evaluatedBeforeUse ? "hemen" : "ilk-kullanimda"
    }

    func report() {
        print("\(label): \(evaluations) degerlendirme, \(uses) kullanim -> \(moment)")
    }
}

func tally(_ probes: [Probe]) {
    for moment in ["hemen", "ilk-kullanimda", "her-kullanimda", "hic"] {
        let count = probes.filter { $0.moment == moment }.count
        print("\(moment): \(count)")
    }
}
```

Ölçümlerde iki numaralandırma kullanılır. `Weekday` bir `Int` ham değerine sahiptir ve `CaseIterable` ile bütün durumlarını listeler; ilk duruma `1` verildiğinde sonrakiler `2` ve `3` olur. `Reading` ise durumlarıyla birlikte değer taşır: `celsius` bir `Double`, `label` bir `String` alır. Bu bloğun çıktısı yoktur, çünkü yalnızca tipleri tanımlar.

```swift
// Types.swift — ham degerli ve iliskili degerli numaralandirmalar
enum Weekday: Int, CaseIterable {
    case monday = 1, tuesday, wednesday
}

enum Reading {
    case celsius(Double)
    case label(String)
}
```

## Ham Değer

Ham değer, bir durumun derleme zamanında sabit olarak atanmış karşılığıdır. Her durumun ham değeri farklı olmalıdır ve değerler tanımda yazılır. İlk durum için `1` yazıldığında sonraki durumların değeri bir artarak belirlenir. Ham değere `rawValue` özelliği ile ulaşılır ve ters yönde, ham değerden duruma gitmek için `Weekday(rawValue: 3)` biçimi kullanılır. Ters yönün her ham değer için bir durum bulamayacağı açıktır; bu yüzden bu biçim bir isteğe bağlı değer döndürür.

```swift
// main.swift — ham deger, rawValue ile kurma ve allCases
print(Weekday.tuesday.rawValue)
print(Weekday(rawValue: 3) == .wednesday)
print(Weekday(rawValue: 9) == nil)
print(Weekday.allCases.count)
```

```
2
true
true
3
```

Birinci satır `tuesday` durumunun ham değerini verir: ilk durum `1` ile başladığı için `2`'dir. İkinci satır `rawValue: 3` ile kurulan değerin `.wednesday` ile eşit olduğunu gösterir. Üçüncü satır, hiçbir durumun ham değeri olmayan `9` için sonucun `nil` olduğunu gösterir; ilk derste gördüğümüz boş kutu burada bir `Int` dönüşümünün değil, bir durum aramanın sonucudur. Dördüncü satır `CaseIterable`'ın eklediği `allCases` ile üç durumu saydığını gösterir.

Ham değer burada bir kimlik ve dönüşüm aracıdır. Bir ağ yanıtından, bir dosyadan ya da bir veritabanı alanından gelen tamsayıyı güvenli biçimde bir duruma çevirmek için kullanılır ve geçersiz değerin ne yapılacağı konusunda çağıranı karar vermeye zorlar.

Ham değer yalnız tamsayı olmak zorunda değildir. Tipi `String` olan bir numaralandırmada her durumun ham değeri, açıkça yazılmadıysa durumun kendi adıdır. Aynı üç işlemi bir gezegen listesiyle yapalım: ham değeri okumak, ham değerden durum kurmak ve geçersiz bir ham değerle kurmayı denemek.

```swift
// main.swift — String ham deger belirtilmezse durum adidir
enum Planet: String {
    case mercury, venus, earth
}

print(Planet.venus.rawValue)
print(Planet(rawValue: "earth") == .earth)
print(Planet(rawValue: "pluto") == nil)
```

```
venus
true
true
```

Birinci satır `venus` durumunun ham değerinin, hiçbir değer yazılmadığı hâlde `"venus"` olduğunu gösterir. İkinci satır `"earth"` ham değerinin `.earth` durumunu verdiğini, üçüncü satır ise listede olmayan `"pluto"` için sonucun `nil` olduğunu gösterir. Tamsayı örneğindeki ters yön burada da aynı biçimde isteğe bağlı bir değer döndürdü: ham değerden duruma giden yol her zaman bir yokluk olasılığı taşır.

**TS14.** Bu ölçümler `Int` ve `String` ham değerli birer numaralandırma için. Diğer ham değer tipleri (`Double`, `Character`) ve ham değeri yalnızca bir kısmı için yazılmış `Int` durumlarının davranışı ayrıca ölçülmedi.

## İlişkili Değer ve Desen Eşleme

İlişkili değer ham değerden farklı çalışır. Ham değer tanım sırasında sabittir ve aynı durumun her örneğinde aynıdır. İlişkili değer ise durum **kurulurken** belirlenir ve her örnek kendi değerini taşır. `Reading.celsius(21.5)` ile `Reading.celsius(30.0)` aynı durumdur, ama farklı veri taşır. Böyle bir değerin içindekine erişmek için `switch` ile **desen eşleme (pattern matching)** kullanılır: her durumun kolunda ilişkili değer bir adla bağlanır.

```swift
// main.swift — iliskili degerin desen eslemeyle acilmasi
let readings = [Reading.celsius(21.5), Reading.label("sicak")]
for reading in readings {
    switch reading {
    case .celsius(let degrees):
        print("derece", degrees)
    case .label(let text):
        print("etiket", text)
    }
}
```

```
derece 21.5
etiket sicak
```

Dizideki iki `Reading` değeri sırayla `switch`'e girer. İlki `celsius` kolunu seçer ve içindeki `21.5`'i `degrees` adına bağlar; ikincisi `label` kolunu seçer ve `"sicak"` dizesini `text` adına bağlar. Her kolda bağlanan ad yalnızca o kolun gövdesinde geçerlidir ve tipi o durumun ilişkili değerinin tipidir. Derleyici bütün durumların ele alındığını denetler: bir durum atlanırsa `switch` tamamlanmamış sayılır ve eksik durum için bir kol yazmak ya da `default` kullanmak gerekir.

Bu davranış, ilk dersteki isteğe bağlı değer ile aynı kalıptır. `Optional` de bir numaralandırmadır ve `.some` durumu bir ilişkili değer taşır; `if let` ve `switch` içindeki `case .some(let value)` aynı eşlemenin iki yazılışıdır. Bu ders, o dersteki kutunun neden böyle davrandığını gösteren ikinci bir örnek verir.

Tek bir duruma bakmak gerektiğinde `switch` yazmak ağır kaçar. `if case` aynı eşlemeyi tek bir koşul olarak yazar: durum eşleşirse ilişkili değer bağlanır ve blok koşar, eşleşmezse `else` kolu koşar. Virgülle bir koşul daha eklenebilir; ilişkili değer bağlandıktan sonra o koşulda kullanılır.

```swift
// main.swift — if case ile tek bir duruma bakmak
let current = Reading.celsius(18.0)
if case .celsius(let degrees) = current, degrees < 20 {
    print("serin", degrees)
}
if case .label(let text) = current {
    print("etiket", text)
} else {
    print("etiket degil")
}
```

```
serin 18.0
etiket degil
```

Birinci `if case`, `current` değerini `celsius` durumuyla eşleştirdi, `18.0`'ı `degrees` adına bağladı ve virgülden sonraki `degrees < 20` koşulunu da geçti. İkinci `if case` aynı değeri `label` durumuyla eşleştirmeye çalıştı, eşleşme olmadığı için `else` kolu koşturdu. Bu, `switch` ile aynı davranıştır: eşleşmeyen durumda ilişkili değer hiç bağlanmaz ve ilgili ad kapsamda yoktur.

**TS15.** Bu ölçüm iki durumlu ve her durumunda tek ilişkili değer olan bir numaralandırma için. Birden çok ilişkili değer taşıyan durumlar, `indirect` numaralandırmalar ve `where` koşullu kollar ölçülmedi.

## İlişkili Değer Ne Zaman Kurulur

İlişkili değer, durum kurulurken verilen bir ifadedir. `Reading.celsius(stamp.eval(19.0))` yazıldığında `stamp.eval(19.0)` ifadesi durum kurulurken bir kez değerlendirilir ve sonuç durumun içinde saklanır. Sonradan `switch` ile okunduğunda ifade yeniden hesaplanmaz; okunan şey durumun içindeki saklı değerdir. İki kez okuyarak bunu ölçelim.

```swift
// main.swift — iliskili deger case kurulurken bir kez degerlendirilir
let stamp = Probe("iliskili-deger")
let reading = Reading.celsius(stamp.eval(19.0))

for _ in 1...2 {
    _ = stamp.use { () -> Double in
        switch reading {
        case .celsius(let degrees):
            return degrees
        case .label:
            return -1
        }
    }
}
stamp.report()
```

```
iliskili-deger: 1 degerlendirme, 2 kullanim -> hemen
```

Bir değerlendirme, iki kullanım ve an **hemen**. Değerlendirme, `reading` kurulduğu satırda gerçekleşti, `use` çağrılarından önce. Her iki `switch` aynı saklı değeri okudu ve ifadeyi yeniden koşturmadı. Bu, ham değerden farklıdır: ham değerin ifadesi hiç koşmaz, çünkü o bir sabittir. İlişkili değerin ifadesi ise örnek başına bir kez koşar.

Ölçümün gösterdiği pratik sonuç şudur: ilişkili değere yazılan pahalı bir hesaplama, durum kurulurken ödenir ve okuyuşlar ek bir hesap gerektirmez. Hesabın okunduğu anda yapılmasını isteyen kod, ilişkili değeri değil bir hesaplanan özelliği kullanmalıdır. Bir sonraki bölüm bu özelliği ölçer.

**TS16.** Bu ölçüm sabit bir `Double` literalini sarmalayan bir ifade için. İlişkili değerin bir işlev çağrısı ya da başka bir ilişkili değer içeren ifade olduğu durumlar ayrıca ölçülmedi.

## Sınırlayıcı Ölçüm

Ham değer ve ilişkili değer durum kurulurken ya da tanımda sabitlenir; yani okuyuş maliyetsizdir. Numaralandırma ise saklanan değer dışında bir de **hesaplanan özellik (computed property)** taşıyabilir. Bu özellik bir değer saklamaz, her okunduğunda gövdesini çalıştırır. `Sensor` numaralandırmasında `fahrenheit` özelliği, ilişkili değer olarak taşınan Celsius derecesini her okunuşta Fahrenheit'a çevirir. Çevirme ifadesi bir `Probe` ile işaretlidir ve özellik iki kez okunur.

```swift
// main.swift — numaralandirmanin hesaplanan ozelligi her okunusta kosar
enum Sensor {
    case reading(Probe, Double)

    var fahrenheit: Double {
        switch self {
        case .reading(let probe, let celsius):
            return probe.eval(celsius * 9 / 5 + 32)
        }
    }
}

let derived = Probe("hesaplanan-ozellik-sensor")
let sensor = Sensor.reading(derived, 20)
_ = derived.use { sensor.fahrenheit }
_ = derived.use { sensor.fahrenheit }
derived.report()
print(sensor.fahrenheit)
```

```
hesaplanan-ozellik-sensor: 2 degerlendirme, 2 kullanim -> her-kullanimda
68.0
```

İki okuyuş, iki değerlendirme, an **her kullanımda**. Hesaplanan özellik sonucu saklamaz; `sensor.fahrenheit` her yazıldığında gövdesi baştan koşar. İlişkili değer `20` ise kurulurken sabitlenmişti, ama ondan türeyen `68.0` her okunuşta yeniden hesaplanır. Çıktının ikinci satırı, aynı özelliğin bir sonraki okunuşunda aynı sonucu verdiğini gösterir.

Bu sonuç dersin kuralını daraltır. "İlişkili değer durum kurulurken bir kez değerlendirilir" cümlesi yalnızca ilişkili değerin kendisi için doğrudur. İlişkili değerden türeyen her hesaplanan özellik, her okunuşta baştan çalışır. Aynı hesabın birden çok yerde gerektiği durumda sonucu bir adda tutmak, hesaplanan özelliği her yerde yeniden okumaktan ucuzdur.

Ham değer için de bir sınır vardır ve o ölçülemez, çünkü derlenmez. Ham değer, kaynakta yazılan bir sabit olmak zorundadır. Aşağıdaki parça bir işlevin dönüşünü ham değer olarak atamaya çalışır ve derlenmez: derleyici onu reddeder. Hata iletisi, ham değerin bir sabit yazım olması gerektiğini bildirdi. Parça burada yalnızca anlatım için durur.

```swift
func rawOf() -> Int { 3 }
enum Bad: Int {
    case a = 1
    case b = rawOf()   // derlenmez: ham deger bir sabit olmali
}
```

Bu sınır iki değer çeşidinin bir ikinci farkını gösterir. İlişkili değer çalışma zamanında hesaplanan herhangi bir ifade olabilir; ham değer ise derleme zamanında bilinen bir sabittir. Ham değerin ifadesi bu yüzden hiçbir zaman çalışma zamanında değerlendirilmez.

**TS17.** Bu ölçüm iki saklı değer üzerinden türeyen tek bir hesaplanan özellik için. Salt okunur olmayan hesaplanan özellik (`set` içeren) ve numaralandırmanın yöntemleri ayrıca ölçülmedi. Reddedilen ham değer parçasında yalnızca işlev çağrısı denendi; başka ifade biçimleri denenmedi.

## Üç Değerin Yan Yana Okunuşu

Derste üç ayrı değer çeşidi ölçüldü ve her biri başka bir ana düştü. Ham değer tanımda yazılan bir sabittir; ifade olarak hiçbir zaman çalışma zamanında koşmaz, bu yüzden bir ölçüm probu ona bağlanamaz. İlişkili değer, durum kurulurken verilen bir ifadedir ve örnek başına bir kez değerlendirilir; ölçümde bu an **hemen** çıktı. Hesaplanan özellik ise bir değer saklamaz, her okunuşta gövdesini koşturur; ölçümde bu an **her kullanımda** çıktı.

Bu üç çeşit birbirinin yerine kullanılabilir gibi görünse de ayrı sorulara yanıt verir. Dışarıdan gelen bir kodu bir duruma çevirmek gerekiyorsa ham değer uygundur, çünkü ters yön bir isteğe bağlı değer döndürür ve geçersiz girdiyi görünür kılar. Durumun yanında örneğe özgü veri taşımak gerekiyorsa ilişkili değer uygundur, çünkü bir durumun farklı örnekleri farklı veri taşıyabilir. Taşınan veriden türeyen bir sonucu gerektiği anda üretmek gerekiyorsa hesaplanan özellik uygundur, ama her okunuşta ödenen bedeli de hesaba katmak gerekir.

## Özet

- Ham değer tanımda sabitlenir ve `Weekday(rawValue:)` bir isteğe bağlı değer döndürür; bulunamayan değer `nil` verir.
- `switch` ile desen eşleme, ilişkili değeri her kolda bir adla bağlar ve bütün durumların ele alınmasını denetler.
- İlişkili değer durum kurulurken bir kez değerlendirilir; okuyuşlar ifadeyi yeniden koşturmaz.
- Numaralandırmadaki hesaplanan özellik sonucu saklamaz ve her okunuşta yeniden koşar.
- Ham değer derleme zamanında bilinen bir sabit olmak zorundadır; işlev çağrısı ham değer olamaz.
- Bu dersin anı: **hemen**. İlişkili değerin ifadesi durum kurulduğu satırda değerlendirilir.

## Sonraki Adım

Bu derste bir numaralandırmadaki özelliğin her okunuşta koştuğunu gördük. Özellikler yalnız numaralandırmaya ait değildir: yapılar ve sınıflar da saklanan, hesaplanan ve gözlemleyen özellik taşır, ayrıca bir ifadenin ilk okunuşa ertelenmesini sağlayan `lazy` vardır. Bir sonraki ders bu özellik çeşitlerini ve her birinin değerini ne zaman kurduğunu ölçer.
