---
title: İşleçler
source: 'https://academia.sh/tr/kurslar/swift/islecler'
course: 'Swift Dili'
language: tr
updated: '2026-10-21T05:03:11+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Aritmetik, karşılaştırma ve aralık işleçlerinin sonuçlarını okumak'
    - '`||` ve `&&` işleçlerinin sağ tarafının ne zaman değerlendirilmediğini göstermek'
    - 'Kısa devre değerlendirmenin işleçte değil parametre tipinde olduğunu açıklamak'
---

# İşleçler

Aritmetik, karşılaştırma ve aralık işleçlerini tanıtır; `||`, `&&` ve üçlü işlecin sağ tarafının hiç değerlendirilmeyebileceğini ölçer.

Dizginin ifade yerleştirmesi her kullanımda yeniden kuruluyordu. Bir işleç de iki ifadeyi birleştirir; soru şu: ikisi de değerlendiriliyor mu? Önceki bir kursta (M10/K03) "kaç kez koştu" bir sayıydı; bu kurs bir an soruyor ve işleçlerde en dikkat çekici an `hic`'tir.

## Aritmetik, Karşılaştırma ve Aralık

Aritmetik işleçler `+`, `-`, `*`, `/` ve `%`'dir. İki `Int`'i bölmek `Int` verir: `7 / 2` değeri 3'tür ve `7 % 2` bölümden kalan 1'dir; `7.0 / 2` ise 3.5 verir. Karşılaştırma işleçleri `<`, `>`, `==` gibi bir `Bool` döndürür. Aralık işleçleri (range operators) bir değer dizisi kurar: `1...4` her iki ucu içerir, `1..<4` üst ucu dışarıda bırakır. `contains` aralığın bir değeri içerip içermediğini söyler.

İşleç öncelikleri matematikteki gibidir: çarpma ve bölme toplamadan önce gelir, parantez sırayı değiştirir. Karşılaştırma işleçleri `Bool` döndürdüğü için doğrudan bir `if` koşulu olabilir; bir sonraki derste bunu kullanacağız. `==` iki değerin eşit olup olmadığını sorar, tek `=` ise atama yapar ve ikisini karıştırmak yaygın bir hatadır. Aralıklar da bir değerdir: `1...4` bir sabite atanabilir, bir döngüde dolaşılabilir ya da `Array(...)` ile diziye çevrilebilir.

Ölçü aracı yine aynı yardımcı dosya. Her `Probe` sarmaladığı ifadenin kaç kez değerlendirildiğini ve kaç kez kullanıldığını sayar; ikisinin ilişkisi anı verir.

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

Şimdi ölçüm bloğu. Her satır bir sonucu gösterir, ardından üç `Probe` kendi raporunu basar. Okurken şuna bak: önce işleçlerin sonuçları, sonra sağ tarafı ölçülen üç ifade. `isOpen` doğru olduğu için `||`'nin sağı hiç gerekmez; üçlü işlecin (`koşul ? a : b`) seçilmeyen dalı da öyle.

```swift
// main.swift — isleclerin sonuclari ve sag tarafi
print(7 / 2, 7 % 2, 7.0 / 2)
print((1...4).contains(4), (1..<4).contains(4))
print(Array(1..<4))

let orProbe = Probe("veya-isleci-sagi")
let andProbe = Probe("ve-isleci-sagi-dogru")
let ternaryProbe = Probe("uclu-isleci-dali")

let isOpen = true
_ = orProbe.use { isOpen || orProbe.eval(true) }
_ = orProbe.use { isOpen || orProbe.eval(true) }
_ = andProbe.use { isOpen && andProbe.eval(true) }
_ = andProbe.use { isOpen && andProbe.eval(true) }
_ = ternaryProbe.use { isOpen ? 1 : ternaryProbe.eval(2) }
_ = ternaryProbe.use { isOpen ? 1 : ternaryProbe.eval(2) }

let allProbes = [orProbe, andProbe, ternaryProbe]
for probe in allProbes { probe.report() }
tally(allProbes)
```

```
3 1 3.5
true false
[1, 2, 3]
veya-isleci-sagi: 0 degerlendirme, 2 kullanim -> hic
ve-isleci-sagi-dogru: 2 degerlendirme, 2 kullanim -> her-kullanimda
uclu-isleci-dali: 0 degerlendirme, 2 kullanim -> hic
hemen: 0
ilk-kullanimda: 0
her-kullanimda: 1
hic: 2
```

`veya-isleci-sagi` iki kullanımda sıfır değerlendirme gösterdi: `isOpen` doğruyken `||` sağ tarafa bakmaz. Üçlü işlecin seçilmeyen dalı da aynı: `uclu-isleci-dali` iki kullanımda `hic`. `&&` ise sol taraf doğru olduğu için sağa geçer ve sağ taraf her kullanımda yeniden değerlendirilir. Üç satır, iki sonuç: aynı sağ taraf ifadesi, işlecin sol tarafına göre ya hiç ya her seferinde değerlendirilir.

**DT32.** `isOpen` bir sabittir; sol tarafın başka bir değeri için sağ tarafın değerlendirilmesi bu derste ölçülmedi.

**DT33.** `7 / 2` ve `7 % 2` ifadelerinin sonuçları bu bloğun çıktısında görülür; başka işleç öncelikleri ölçülmedi.

## Aralık İşleçleri

Swift iki aralık işleci sunar: kapalı aralık `1...3` her iki ucu da içerir, yarı açık aralık `1..<3` üst ucu dışarıda bırakır. Aralıklar bir döngüde, bir dilimlemede ya da bir kıyaslamada kullanılabilir ve `Array(...)` ile bir diziye çevrilebilir. Aralığın uç değerleri sıradan ifadelerdir; işleç yalnız bu iki ucu birleştirir.

Aşağıdaki blok iki aralık kurar. Kapalı aralığın üst ucu bir `Probe`'dan, yarı açık aralığın üst ucu başka bir `Probe`'dan gelir. Her aralık iki kez okunur: biri `count`, biri bir dizi olarak. Sonra iki aralığın içeriği yazdırılır.

```swift
// Range.swift — kapali ve yari acik aralik
let closedProbe = Probe("kapali-aralik")
let halfProbe = Probe("yari-acik-aralik")
let closed = 1...closedProbe.eval(3)
let half = 1..<halfProbe.eval(3)
_ = closedProbe.use { closed.count }
_ = closedProbe.use { Array(closed) }
_ = halfProbe.use { half.count }
_ = halfProbe.use { Array(half) }
print(Array(closed), Array(half))
print(closed.contains(3), half.contains(3))
closedProbe.report()
halfProbe.report()
```

```
[1, 2, 3] [1, 2]
true false
kapali-aralik: 1 degerlendirme, 2 kullanim -> hemen
yari-acik-aralik: 1 degerlendirme, 2 kullanim -> hemen
```

Kapalı aralık `[1, 2, 3]`, yarı açık aralık ise `[1, 2]` verdi; aynı üst uç 3 bir yerde içeride, bir yerde dışarıda kaldı. `contains(3)` satırı bunu doğruluyor. İki `Probe` da tek bir değerlendirme gösterdi: üst uç, aralık kurulurken bir kez hesaplandı ve sonraki okumalar yeniden hesaplamadı. Aralık bir değer olduğu için, ucu hesaplayan ifade tanım satırında çalışır; okumalar hazır değeri kullanır.

Aralık işleçlerinin güvenliği buradan gelir: uç ifadesi kısa devre yapmaz, hepsi hemen hesaplanır. Bu, daha önce gördüğümüz `&&` ve `||` işleçlerinden farklıdır, çünkü onların sağı koşula bağlıydı.

**DT34.** Aralıklar tam sayı uçlarıyla ve `Int` değerlerle ölçüldü; ondalıklı aralıkların ve `stride` ile adım atlamalı aralıkların davranışı bu dersin dışındadır.

## Bileşik Atama ve İşleç Önceliği

Bileşik atama işleçleri bir değişkeni okuyup yeni değerle aynı yere yazar: `score += 3` ile `score = score + 3` aynı iş içindir. `-=`, `*=` ve `/=` aynı kalıba uyar. İşleçler ayrıca bir öncelik sırasına sahiptir: çarpma toplamadan önce işler, bu yüzden `2 + 3 * 4` 14 verir; parantez bu sırayı değiştirir ve `(2 + 3) * 4` 20 verir.

Ölçülecek şey, bileşik atamanın sağ tarafının her çalıştığında yeniden değerlendirilmesidir. Aşağıdaki blok bir `score` değişkenini iki kez artırır. Her artış, bir `Probe`'dan gelen bir çarpanı içerir. Önceliğin iki sonucu da aynı blokta yazdırılır.

```swift
// Compound.swift — bilesik atama ve oncelik
let stepProbe = Probe("artis-carpani")
var score = 2
_ = stepProbe.use { score += stepProbe.eval(3) * 2 }
_ = stepProbe.use { score += stepProbe.eval(3) * 2 }
print(score)
print(2 + 3 * 4, (2 + 3) * 4)
stepProbe.report()
```

```
14
14 20
artis-carpani: 2 degerlendirme, 2 kullanim -> her-kullanimda
```

`score` 2 ile başladı ve iki artıştan sonra 14 oldu; her artış `3 * 2` olan 6 ekledi. `2 + 3 * 4` ifadesi 14, parantezli biçim 20 çıktı. Ölçüm satırı iki değerlendirme gösterdi: bileşik atamanın sağ tarafı her çalıştığında yeniden hesaplanır. Bu yüzden an `her-kullanimda` olur; `+=` bir kez yazıldığı hâlde iki kez çalıştı.

Bileşik atamayı bir kısaltma olarak okuyabilirsin, ama kısaltmanın sağ tarafı yeniden değerlendirilen bir ifadedir. Sağ taraf yan etkili bir çağrıysa, bunu atamanın her çalışmasında beklemelisin.

**DT35.** Bileşik atama `Int` ile ölçüldü; ondalıklı sayılarda ya da dizgilerde `+=` davranışı bu dersin dışındadır.

## Bölme ve Kalan

Tam sayı bölmesi sonucu tam sayı olarak keser: `7 / 2` 3 verir, 3.5 vermez. `%` işleci bölmeden kalanı döndürür: `7 % 2` 1 verir. Negatif sayılarda kalanın işareti bölünenin işaretini izler: `-7 % 3` -1 çıkar. Kesirli sonuç istiyorsan her iki tarafı da ondalıklı yazarsın: `7.0 / 2` 3.5 verir. Sıfıra bölmek ise programı durdurur; ders bunu çalıştırmaz.

Aşağıdaki blok bir tam sayıyı hem bölen hem bölünen olarak ayıran bir fonksiyon yazar. Bölen bir `Probe` üzerinden iki kez okunur: bir kez bölüm, bir kez kalan için. Fonksiyon bir pozitif ve bir negatif sayıyla çağrılır.

```swift
// Division.swift — bolme ve kalan
func divide(_ number: Int, probe: Probe) -> (Int, Int) {
    (number / probe.eval(2), number % probe.eval(2))
}
let divisorProbe = Probe("bolen")
print(divisorProbe.use { divide(7, probe: divisorProbe) })
print(divisorProbe.use { divide(-7, probe: divisorProbe) })
print(7.0 / 2, -7 % 3)
divisorProbe.report()
```

```
(3, 1)
(-3, -1)
3.5 -1
bolen: 4 degerlendirme, 2 kullanim -> her-kullanimda
```

`divide(7)` `(3, 1)`, `divide(-7)` ise `(-3, -1)` verdi: bölüm sıfıra doğru kesildi ve kalan bölünenin işaretini aldı. Ondalıklı bölme 3.5, `-7 % 3` ise -1 çıktı. Ölçüm satırında dört değerlendirme var, çünkü her çağrı bölen ifadesini iki kez yazıyor. İki çağrı bu yüzden dört değerlendirme getirdi ve an `her-kullanimda` okunur.

Bu ölçümün gösterdiği küçük bir tuzak da var: aynı ifadeyi iki yerde yazmak iki değerlendirme demektir. Değeri bir kez hesaplayıp bir sabite almak hem sayıyı azaltır hem okunuşu sadeleştirir.

**DT36.** Bölme ve kalan `Int` ile ölçüldü; sıfıra bölme ve `Int.min / -1` gibi durduran durumlar bu derste çalıştırılmaz.

## Üçlü Koşul İşleci

`koşul ? a : b` biçimindeki üçlü işleç, koşula göre iki değerden birini seçer. Koşul `true` ise `a`, değilse `b` sonuç olur. İşlecin üç operandı vardır ve sıralaması hep aynıdır: önce koşul, sonra "doğruysa" ifadesi, sonra "yanlışsa" ifadesi. Küçük bir `if`-`else` ifadesinin değer üreten kısa biçimidir.

Burada ölçülecek kural, seçilmeyen kolun hiç çalışmamasıdır. Aşağıdaki blok iki kolu da ayrı bir `Probe`'a bağlar ve işleci iki kez `true` koşuluyla çalıştırır.

```swift
// Ternary.swift — uclu kosul isleci
let yesProbe = Probe("dogru-kol")
let noProbe = Probe("yanlis-kol")
func choose(_ flag: Bool, yes: Probe, no: Probe) -> Int {
    flag ? yes.eval(10) : no.eval(20)
}
_ = yesProbe.use { choose(true, yes: yesProbe, no: noProbe) }
_ = noProbe.use { choose(true, yes: yesProbe, no: noProbe) }
print(choose(true, yes: yesProbe, no: noProbe))
yesProbe.report()
noProbe.report()
```

```
10
dogru-kol: 3 degerlendirme, 1 kullanim -> her-kullanimda
yanlis-kol: 0 degerlendirme, 1 kullanim -> hic
```

`choose(true)` her çağrıda `10` verdi. `dogru-kol` üç değerlendirme gösterdi: iki `use` çağrısı ve son `print` içindeki çağrı, üçü de doğru kola gitti. `yanlis-kol` ise sıfır değerlendirmeyle `hic` çıktı, çünkü hiçbir çağrıda seçilmedi. Koşul doğru olduğunda yanlış kolun ifadesi derlenir ama hiç çalıştırılmaz.

Bu, `&&` ve `||` ile aynı kurala dayanır: sonuç belli olduğunda kalan ifade değerlendirilmez. Üçlü işleçte yan etkili bir çağrıyı bir kola koyduğunda, o çağrının yalnız o kol seçildiğinde çalışacağını bilirsin.

Üçlü işleç ifade olduğu için bir değer üretir; bu yüzden bir sabite doğrudan atanabilir ya da bir fonksiyona argüman olarak verilebilir. Koşul uzadığında ya da kollar karmaşıklaştığında `if`-`else` ve ayrı bir sabit, aynı kuralı daha okunur yazmanın yoludur.

Bir kolun yan etkisi yoksa seçilmemesi fark edilmez; yan etkisi varsa, örneğin bir sayacı artırıyorsa ya da bir kaydı değiştiriyorsa, seçilmeyen kolda bu etkinin hiç gerçekleşmediğini bilmek hatayı önler. Ölçüm tam olarak bu farkı sayıyla gösterdi.

**DT37.** Üçlü işleç iki `Int` koluyla ölçüldü; iç içe üçlü işleçlerin okunurluğu bu dersin dışındadır.

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

Kısa devre değerlendirme (short-circuit evaluation), `||` ve `&&` işleçlerinin ikinci parametresini `@autoclosure` ile almasından gelir. Bir işleç, ikinci parametresini `@autoclosure` ile alan bir fonksiyondur; sağ taraf gerekmezse hiç çağrılmaz. Aynı işi yapan ama ikinci parametresini sıradan `Bool` alan bir fonksiyon sağ tarafı çağrıdan önce değerlendirir. Aşağıda bu iki imza yan yana durur. Her ikisini de iki kez, sol taraf yanlışken çağırıyoruz; böylece sağ tarafın değerlendirilmesi gerekmez ve fark yalnız imzadan doğar.

```swift
// main.swift — sag tarafin tipi: Bool ve autoclosure
func both(_ left: Bool, _ right: Bool) -> Bool { left && right }
func lazyBoth(_ left: Bool, _ right: @autoclosure () -> Bool) -> Bool { left && right() }

let eagerProbe = Probe("both-sagi")
let autoProbe = Probe("lazyboth-sagi")

_ = eagerProbe.use { both(false, eagerProbe.eval(true)) }
_ = eagerProbe.use { both(false, eagerProbe.eval(true)) }
_ = autoProbe.use { lazyBoth(false, autoProbe.eval(true)) }
_ = autoProbe.use { lazyBoth(false, autoProbe.eval(true)) }

let allProbes = [eagerProbe, autoProbe]
for probe in allProbes { probe.report() }
tally(allProbes)
```

```
both-sagi: 2 degerlendirme, 2 kullanim -> her-kullanimda
lazyboth-sagi: 0 degerlendirme, 2 kullanim -> hic
hemen: 0
ilk-kullanimda: 0
her-kullanimda: 1
hic: 1
```

İki fonksiyonun gövdesi aynı: `left && right`. `both` sağ tarafı çağrıdan önce değerlendirir, gövde `left` yanlış olduğu için kullanmasa da; kural `her-kullanimda` der. `lazyBoth` ise sağ tarafı bir kapanışa sarar ve gövde ona hiç dokunmaz: `hic`. Farkı yaratan işleç değil, parametre tipidir.

**DT38.** `@autoclosure` bu derste yalnız sağ tarafı erteleyen bir imza olarak ölçüldü; kapanış ayrıntıları kapanışlar dersine kalıyor.

Burada öğrenilen pratik sonuç şu: bir ifadenin sağ tarafında yan etkisi olan bir çağrı varsa, o çağrının koşulsuz çalışacağını varsaymak yanlıştır. `&&` ve `||` ile kurulan koşullar sırayla okunur ve soldaki ifade sonucu belirlediyse sağdaki hiç çalışmaz. Bir hesabın her durumda yapılmasını istiyorsan, onu işlecin dışında bir sabite al ve sonucu işleçte kullan.

## Özet

- `/` iki `Int` için `Int` verir, `%` kalanı verir; `...` ve `..<` aralık kurar.
- `||`, `&&` ve üçlü işlecin sağ tarafı gerekmezse hiç değerlendirilmez.
- Kısa devre işleçte değil, ikinci parametrenin `@autoclosure` olmasında yaşar.
- Aynı gövdeyi `@autoclosure` olmadan yazarsan sağ taraf her çağrıda değerlendirilir.
- Bu dersin anı: **hiç** (sol taraf doğruyken `||` işlecinin sağı).

## Sonraki Adım

Bir ifadenin hiç değerlendirilmediği başka bir yer var: `switch`'in ilk eşleşmeden sonraki dalları. Sıradaki ders denetim akışına, koşullara ve döngülere bakıyor.
