---
title: "Swift'in Tasarım Hedefleri"
source: 'https://academia.sh/tr/kurslar/swift/swiftin-tasarim-hedefleri'
course: 'Swift Dili'
language: tr
updated: '2026-10-21T05:03:11+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - "Swift'in güvenlik, ifade gücü ve başarım hedeflerini somut davranışlarla ilişkilendirmek"
    - 'Bir ifadenin değerlendirildiği anı hemen, ilk kullanımda, her kullanımda ve hiç olarak sınıflamak'
    - 'Ölçüm düzeneğindeki `Probe` sınıfının kuralını ve sınırını açıklamak'
---

# Swift'in Tasarım Hedefleri

Swift'in üç hedefini — güvenlik, ifade gücü, başarım — bir ölçü eksenine bağlar: bu ifade ne zaman değerlendiriliyor? Sekiz ifadeyi dört ana ayırır.

Önceki kurslarda bir programın ne yaptığını sordun. Bu kurs başka bir şey soruyor: bir ifade yazdığında, o ifade programın hangi anında çalışıyor? Derleme ile koşum arasındaki ayrımı önceki bir kursta (M11/K01) gördün; burada koşum içindeki sırayı ölçeceğiz. Swift iOS müfredatının dilidir, ve onu üç hedefle tanıtmak gelenektir.

## Üç Hedef

Güvenlik: dil, hatayı koşumdan önce yakalamaya çalışır. Bir sabit atanmadan okunamaz; bir değer, tipi isteğe bağlı değer (optional) olmadıkça `nil` olamaz. İki durumda da derleyici programı reddeder. Bu parçalar Swift 6.4'te derlenmez; derleyici ikisini de reddeder, bu yüzden çıktısız kalırlar.

```swift
let total: Int
print(total)
```

```swift
var name: String = nil
```

İfade gücü: tipi yazmak zorunda kalmazsın, derleyici sağ taraftan çıkarır (tip çıkarımı, type inference). Başarım hedefi ise bu derste ölçülmez; süre ölçmüyoruz, yalnız sıra ölçüyoruz.

## Ölçü Ekseni: Dört An

Kurs boyunca tek bir soru soracağız: bu ifade ne zaman değerlendiriliyor? Dört cevap var: **hemen**, **ilk kullanımda**, **her kullanımda** ve **hiç**. Ölçüm düzeneği iki parçadan oluşur. Önce yardımcı dosya; ders boyunca aynı kalır ve ilk Swift bloğu olarak hep burada durur.

```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)")
    }
}
```

`eval` ifadeyi sarar ve değerlendirildiğini sayar; `use` ifadeye erişimi sarar. Kural basit: hiç değerlendirilmediyse `hic`; birden çok değerlendirildiyse `her-kullanimda`; bir kez değerlendirildi ve bu ilk kullanımdan önceyse `hemen`; değilse `ilk-kullanimda`.

**DT1.** Her gözlem, `hic` dışında, en az iki kullanım taşır; tek kullanım, tek değerlendirmeyi `hemen` ile `ilk-kullanimda` arasında ayırt edemez.

Sekiz ifade, sekiz `Probe`. Sabit, tembel özellik, hesaplanan özellik, fonksiyon, kısa devre ve kapanış aynı dosyada yan yana durur; kurs bunları sırayla ayrı derslere bölecek.

```swift
// main.swift — sekiz ifade, dort an
final class Basket {
    let lazyProbe: Probe
    let computedProbe: Probe
    var items = [3, 4, 5]

    init(lazyProbe: Probe, computedProbe: Probe) {
        self.lazyProbe = lazyProbe
        self.computedProbe = computedProbe
    }

    lazy var total: Int = lazyProbe.eval(items.reduce(0, +))
    var count: Int { computedProbe.eval(items.count) }
}

func square(_ x: Int, probe: Probe) -> Int { probe.eval(x * x) }

let constant = Probe("let-sabiti")
let lazyTotal = Probe("lazy-ozellik")
let computed = Probe("hesaplanan-ozellik")
let fallback = Probe("bos-birlestirme-sagi")
let call = Probe("fonksiyon-govdesi")
let shortCircuit = Probe("ve-isleci-sagi")
let captured = Probe("yakalama-listesi")
let body = Probe("kapanis-govdesi")

let limit = constant.eval(10)
_ = constant.use { limit }
_ = constant.use { limit }

let basket = Basket(lazyProbe: lazyTotal, computedProbe: computed)
_ = lazyTotal.use { basket.total }
_ = lazyTotal.use { basket.total }
_ = computed.use { basket.count }
_ = computed.use { basket.count }

let stored: Int? = 7
_ = fallback.use { stored ?? fallback.eval(0) }
_ = fallback.use { stored ?? fallback.eval(0) }

_ = call.use { square(3, probe: call) }
_ = call.use { square(4, probe: call) }

let ready = false
_ = shortCircuit.use { ready && shortCircuit.eval(true) }
_ = shortCircuit.use { ready && shortCircuit.eval(true) }

let step = 2
let addStep = { [step = captured.eval(step)] (x: Int) -> Int in x + step }
_ = captured.use { addStep(1) }
_ = captured.use { addStep(2) }

let double = { (x: Int) -> Int in body.eval(x * 2) }
_ = body.use { double(3) }
_ = body.use { double(4) }

let probes = [constant, lazyTotal, computed, fallback, call, shortCircuit, captured, body]
for probe in probes { probe.report() }
tally(probes)
```

```
let-sabiti: 1 degerlendirme, 2 kullanim -> hemen
lazy-ozellik: 1 degerlendirme, 2 kullanim -> ilk-kullanimda
hesaplanan-ozellik: 2 degerlendirme, 2 kullanim -> her-kullanimda
bos-birlestirme-sagi: 0 degerlendirme, 2 kullanim -> hic
fonksiyon-govdesi: 2 degerlendirme, 2 kullanim -> her-kullanimda
ve-isleci-sagi: 0 degerlendirme, 2 kullanim -> hic
yakalama-listesi: 1 degerlendirme, 2 kullanim -> hemen
kapanis-govdesi: 2 degerlendirme, 2 kullanim -> her-kullanimda
hemen: 2
ilk-kullanimda: 1
her-kullanimda: 3
hic: 2
```

Sekiz ifade dört ana bölündü: iki `hemen`, bir `ilk-kullanimda`, üç `her-kullanimda`, iki `hic`. Bu sayı kursun bağlayıcı dökümüdür; sonraki dersler her ifadeyi kendi dersinde açar. `let` sabiti tanımlandığı satırda değerlendirilir. `lazy` özellik ilk okunduğunda kurulur ve saklanır; hesaplanan özellik ise her okumada yeniden hesaplanır. Fonksiyon gövdesi her çağrıda koşar; `??` işlecinin sağı sol dolu olduğu için, `&&` işlecinin sağı sol yanlış olduğu için hiç çalışmaz. Yakalama listesi kapanış oluşturulurken bir kez değerlendirilir; kapanışın gövdesi ise her çağrıda.

**DT2.** Sabit ve yakalama listesi aynı ana düşer, ama yollar farklıdır; bu derste yalnız anı ölçüyoruz, mekanizmayı değil.

## Değer Kopyası Yeniden Hesaplamaz

Swift'in güvenlik hedefinin bir ayağı değer semantiğidir (value semantics): dizi, dizgi ve yapı gibi değer tipleri atamada kopyalanır ve kopya bağımsız bir değerdir. Bir değişkeni diğerine atadığında, ikisinden birini değiştirmek öbürünü etkilemez. Bu özellik tasarımın "yanlışlıkla paylaşılan durum olmasın" kaygısından gelir. Ölçüm sorusu başka: kopya, kaynağı üreten ifadeyi yeniden değerlendirir mi, yoksa yalnız var olan değeri mi çoğaltır?

Aşağıdaki blok bir diziyi bir `Probe` ile üretir, `duplicate` adlı ikinci bir değişkene kopyalar ve iki diziyi birbirinden bağımsız biçimde değiştirir. Ardından her iki değişkeni okur; okumalar iki kullanım sayılır.

```swift
// Copy.swift — kopya ifadeyi tekrar calistirmaz
let sourceProbe = Probe("kaynak-dizi")
var original = sourceProbe.eval([1, 2, 3])
var duplicate = original
duplicate.append(4)
original.append(9)
_ = sourceProbe.use { original.count }
_ = sourceProbe.use { duplicate.count }
print(original, duplicate)
sourceProbe.report()
```

```
[1, 2, 3, 9] [1, 2, 3, 4]
kaynak-dizi: 1 degerlendirme, 2 kullanim -> hemen
```

`original` dizisine eklenen 9, `duplicate` dizisinde görünmedi; `duplicate` dizisine eklenen 4 de `original` dizisinde yok. İki değişken atama anında ayrıldı ve her biri kendi yoluna gitti. Ölçüm satırı ise ifadenin yalnız bir kez değerlendirildiğini söylüyor: atama bir değeri çoğaltır, onu üreten ifadeyi yeniden çalıştırmaz. Değerlendirme `var` tanımında, iki okumadan önce olduğu için an `hemen` çıkar.

Bu ayrım güvenlik hedefini somutlaştırır. Eğer atama kaynağı yeniden hesaplasaydı, her kopya sonucunu başka bir anda üretebilirdi; ölçülen davranışta kopya, atama anındaki değerin bir görüntüsüdür. Sonradan yapılan değişiklikler iki tarafa ayrı ayrı uygulanır.

**DT3.** Kopyanın bağımsızlığı bir `Int` dizisiyle ölçüldü; içinde sınıf örneği taşıyan bir dizinin kopyasında elemanların paylaşılması bu dersin konusu değildir.

## Sabit Bağlama, Nesneyi Dondurmaz

Güvenlik hedefinin bir başka ucu `let` ile ilgilidir ve sık yanlış okunur. Bir sınıf örneğini `let` ile bağladığında, bağlanan şey örneğe giden referanstır. Değişken yerine sabit yazmak, `holder` adının başka bir nesneyi göstermesini engeller, ama nesnenin kendi `var` özelliklerini kilitlemez. Aynı kuralı değer tipleri için ters yönde okuyabilirsin: bir yapıyı `let` ile bağlarsan özelliklerini de değiştiremezsin; sınıfta ise bu yasak yoktur.

Aşağıdaki blok küçük bir sınıf tanımlar, onu `let` ile bağlar ve yine de içindeki sayacı iki kez atayarak değiştirir. Sayaç değeri bir `Probe` üzerinden gelir; iki ayrı atama iki ayrı değerlendirme getirir.

```swift
// Holder.swift — let nesneyi dondurmaz
final class Holder {
    var count = 0
}
let holderProbe = Probe("sinif-sayaci")
let anchor = Holder()
_ = holderProbe.use { anchor.count = holderProbe.eval(5) }
_ = holderProbe.use { anchor.count = holderProbe.eval(8) }
print(anchor.count)
holderProbe.report()
```

```
8
sinif-sayaci: 2 degerlendirme, 2 kullanim -> her-kullanimda
```

`anchor` bir `let` sabiti olduğu halde `anchor.count` iki kez atandı ve son değer olan 8 okundu. Sabit olan, `anchor` adının bağlandığı referanstır; nesnenin içi değişkendir. Ölçüm satırı iki değerlendirme gösteriyor, çünkü iki atama iki ayrı `eval` çağrısı yaptı: `let` kuralı burada atamanın sayısını kısıtlamıyor, çünkü atanan şey `anchor` değil, `anchor.count` alanıdır. Bu yüzden an `her-kullanimda` olur.

Tasarım açısından çıkarım şudur: `let`, bir bağlamanın yeniden yapılamayacağı güvencesidir; nesnenin değişmezliği güvencesi değildir. Değişmezlik istiyorsan alanları da `let` yap ya da değer tipi kullan.

**DT4.** Sınıf örneği tek bir alanla ölçüldü; `let` ile bağlı değer tipinde aynı atamanın derlenmediği iddiası bu dersin dışında, KAYNAK düzeyinde bir bilgidir.

## Tip Çıkarımı Anı Değiştirmez

İfade gücü hedefinin en görünür parçası tip çıkarımıdır: `let size = 12` yazarsan derleyici `Int` tipini kendisi bulur, sen yazmak zorunda kalmazsın. İstersen tipi açıkça da yazarsın: `let size: Int = 12`. Burada akla gelen soru, çıkarımın bir çalışma zamanı maliyeti ya da zamanlaması olup olmadığıdır. Tip çıkarımı derleme sırasında biter; çalışan program tipin nasıl bulunduğunu bilmez.

Aşağıdaki blok aynı değeri iki yolla tanımlar: biri çıkarımla, biri açık tip bildirimiyle. Her biri kendi `Probe`'una bağlıdır ve iki kez okunur; `type(of:)` ile iki değişkenin tipi de yazdırılır.

```swift
// Inference.swift — cikarim ve acik tip ayni ani verir
let inferredProbe = Probe("cikarilan-tip")
let declaredProbe = Probe("acik-tip")
let inferred = inferredProbe.eval(42)
let declared: Int = declaredProbe.eval(42)
_ = inferredProbe.use { inferred + 1 }
_ = inferredProbe.use { inferred + 2 }
_ = declaredProbe.use { declared + 1 }
_ = declaredProbe.use { declared + 2 }
print(type(of: inferred), type(of: declared))
inferredProbe.report()
declaredProbe.report()
```

```
Int Int
cikarilan-tip: 1 degerlendirme, 2 kullanim -> hemen
acik-tip: 1 degerlendirme, 2 kullanim -> hemen
```

İki değişkenin tipi aynı çıktı, ve iki `Probe` aynı anı verdi: ikisi de tek değerlendirme, iki kullanım, `hemen`. Açık tip bildirimi ifadeyi başka bir zamana taşımadı; yalnız derleyiciye ne bulması gerektiğini söyledi. Bu yüzden kursun ölçü ekseni tip çıkarımına duyarsızdır: ifadenin ne zaman değerlendirildiğini belirleyen şey tipin yazılı olup olmaması değil, ifadenin hangi bağlamda durduğudur.

**DT5.** Tip çıkarımı bu derste yalnız `Int` literaliyle ölçüldü; çıkarımın başka literal ve ifade çeşitlerinde zamanlamaya dokunmadığı iddiası bu dersin dışındadır.

## Tembel Dönüşüm Çağrılana Kadar Bekler

Tasarımın ifade gücü hedefi, kısa yazılan şeyin ne zaman çalıştığı sorusunu da doğurur. Bir dizi üzerinde `map` çağırdığında dönüşüm hemen ve her eleman için yapılır. Aynı dizinin `lazy` görünümü üzerinde `map` çağırırsan, dönüşüm tanımlandığı anda hiçbir eleman için çalışmaz; yalnız bir eleman istendiğinde, o eleman için çalışır. Bu, daha önce gördüğümüz `lazy var` özelliğinin dizi karşılığı değildir ama aynı sezgiyi taşır: iş, sonucu isteyene kadar ertelenebilir.

Aşağıdaki blok iki `Probe` kurar. İstekli dönüşümün gövdesi `eagerProbe`'a, tembel dönüşümün gövdesi `lazyProbe`'a değerlendirme yazar. Dönüşümlerin hemen ardından ve tembel görünümden iki eleman çekildikten sonra sayaçlar yazdırılır. `evaluations` özelliği `Probe` içinde okunabilir bir sayaçtır.

```swift
// LazyMap.swift — istekli ve tembel donusum
let eagerProbe = Probe("istekli-donusum")
let lazyMapProbe = Probe("tembel-donusum")
let values = [1, 2, 3]
let eagerDoubled = values.map { eagerProbe.eval($0 * 2) }
let lazyDoubled = values.lazy.map { lazyMapProbe.eval($0 * 2) }
print(eagerProbe.evaluations, lazyMapProbe.evaluations)
_ = lazyMapProbe.use { Array(lazyDoubled.prefix(2)) }
print(eagerProbe.evaluations, lazyMapProbe.evaluations)
_ = lazyMapProbe.use { Array(lazyDoubled.prefix(2)) }
print(eagerDoubled, Array(lazyDoubled.prefix(1)))
lazyMapProbe.report()
```

```
3 0
3 2
[2, 4, 6] [2]
tembel-donusum: 5 degerlendirme, 2 kullanim -> her-kullanimda
```

İlk satır `3 0` çıktı: istekli `map` üç elemanın üçünü hemen dönüştürdü, tembel `map` ise henüz hiçbirine dokunmadı. İkinci satırda tembel sayaç 2 oldu, çünkü `prefix(2)` yalnız iki elemanın dönüşümünü istedi; üçüncü eleman hiç hesaplanmadı. Aynı `prefix(2)` ikinci kez çağrılınca dönüşüm yeniden çalıştı, çünkü tembel görünüm sonuçları saklamaz; son `report` satırındaki beş değerlendirme bunu gösteriyor: iki, iki ve son `prefix(1)` çağrısından bir.

İfade gücü hedefi bu iki davranışı birbirinden ayırt etmeyi sana bırakır. İstekli `map` sonucu bir kez üretir ve saklar. Tembel görünüm yazmayı kısa tutar, ama her çekişte işi yeniden yapabilir. Hangisinin doğru olduğu, sonucun kaç kez okunacağına ve gövdenin yan etkisi olup olmadığına bağlıdır.

**DT6.** Tembel dönüşüm yalnız `prefix` ile çekilen elemanlar için ölçüldü; `lazy` görünümün `filter` ya da zincirlenmiş dönüşümlerde sayıyı nasıl değiştirdiği bu dersin dışındadır.

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

Kural sayar, niyeti okumaz. Aynı `let` ifadesini iki ayrı sabit olarak, iki ayrı `Probe` ile yazarsan ikisi de `hemen` çıkar. Aynı ifadeyi tek `Probe`'a bağlarsan, ikinci `eval` sayıyı ikiye çıkarır ve kural `her-kullanimda` der; kodun niyeti değişmemiştir, ölçüm düzeneği ise değişmiştir.

```swift
// Twin.swift — ayni ifade, iki probe ve tek probe
let first = Probe("birinci-sabit")
let second = Probe("ikinci-sabit")
let shared = Probe("ortak-sabit")

let a = first.eval(5)
let b = second.eval(5)
let c = shared.eval(5)
let d = shared.eval(5)

for probe in [first, second, shared] {
    _ = probe.use { a + b + c + d }
    _ = probe.use { a + b + c + d }
    probe.report()
}
```

```
birinci-sabit: 1 degerlendirme, 2 kullanim -> hemen
ikinci-sabit: 1 degerlendirme, 2 kullanim -> hemen
ortak-sabit: 2 degerlendirme, 2 kullanim -> her-kullanimda
```

**DT7.** Bu ölçüm, ifadenin yazılışını değil, `eval` çağrısının sayısını okur; `Probe`'u dil özelliği saymıyoruz.

## Özet

- Swift güvenliği derleyiciyle sağlar: atanmamış sabit okunamaz, isteğe bağlı olmayan değer `nil` olamaz.
- İfade gücü tip çıkarımıdır; başarım hedefi bu derste ölçülmez.
- Kursun ölçü ekseni: bu ifade ne zaman değerlendiriliyor? Dört an: hemen, ilk kullanımda, her kullanımda, hiç.
- `Probe` kuralı sayıyı okur; niyeti okumaz.
- Bu dersin anı: **hemen** (`let` sabiti, tanımlandığı satırda).

## Sonraki Adım

Sabit tanımlandığı anda değerlendirilir; peki `var` yeniden atanınca ne olur, ve bir sabit tanımlandıktan sonra atanabilir mi? Sıradaki ders, sabitlerle değişkenlerin atama anlarını ölçüyor.
