---
title: 'Temel Tipler'
source: 'https://academia.sh/tr/kurslar/swift/temel-tipler'
course: 'Swift Dili'
language: tr
updated: '2026-10-21T05:03:11+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - '`Int`, `Double`, `Bool` ve `String` tiplerinin rollerini ayırt etmek'
    - 'Tipler arası dönüşümün açık yazıldığını ve ne zaman yapıldığını söylemek'
    - 'Kayan noktalı karşılaştırmanın neden beklenmedik sonuç verdiğini açıklamak'
    - 'Demet elemanlarının soldan sağa ve okunmasa da değerlendirildiğini göstermek'
---

# Temel Tipler

`Int`, `Double`, `Bool` ve `String` tiplerini tanıtır; dönüşümün açık olduğunu ve bir dönüşüm ifadesinin hemen değerlendirildiğini ölçer.

Sabit ve değişkenin atama anını gördük: tanımlandığı satırda, `hemen`. Şimdi atanan değerin kendisine bakıyoruz. Swift'in dört temel tipi var: tam sayı için `Int`, kayan noktalı sayı için `Double`, mantıksal değer için `Bool` ve dizgi (string) için `String`. Bu dersin sorusu şu: bir tipi başka bir tipe çeviren ifade ne zaman değerlendiriliyor?

## Dönüşüm Açıktır

Swift iki tipi kendiliğinden karıştırmaz. `Int` ile `Double` toplamak istersen derleyici programı reddeder: aşağıdaki parça Swift 6.4'te derlenmez, bu yüzden çıktısızdır.

```swift
let count = 1
let size = 2.5
print(count + size)
```

Çözüm dönüşümü yazmaktır: `Double(count)`. Dönüşüm kendi başına bir ifadedir ve bir `let` içine yazılırsa o satırda bir kez değerlendirilir. Bu dersin ölçümü bunu doğrular. Önce her derste aynı kalan yardımcı dosya.

```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çüm iki `Probe` ile başlar: biri dönüşümü, ikincisi bir demet elemanını izler. Dönüşümün hemen yanında iki kayan noktalı gözlem ve bir `Int.max` basımı durur; çünkü `Double` karşılaştırmasının neden sürpriz verdiği bu dersin konusudur. `marked` yardımcı fonksiyonu demet elemanlarının sırasını `print` ile gösterir. `unusedProbe` ise hiç okunmayan bir demet elemanını izler.

```swift
// main.swift — donusum ve demet ani
let conversionProbe = Probe("tip-donusumu")
let tupleProbe = Probe("demet-elemani")
let unusedProbe = Probe("okunmayan-eleman")

let wholeCount = 7
let ratio = conversionProbe.eval(Double(wholeCount) / 2)
_ = conversionProbe.use { ratio }
_ = conversionProbe.use { ratio }
print(ratio)
print(Int.max)
print(0.1 + 0.2 == 0.3)
print(0.1 + 0.2)

func marked(_ n: Int) -> Int { print("deger \(n)"); return n }
let triple = (marked(1), marked(2), marked(3))
print(triple.1)

let record = (size: tupleProbe.eval(3), spare: unusedProbe.eval(9))
_ = tupleProbe.use { record.size }
_ = tupleProbe.use { record.size }

let allProbes = [conversionProbe, tupleProbe, unusedProbe]
for probe in allProbes { probe.report() }
tally(allProbes)
```

```
3.5
9223372036854775807
false
0.30000000000000004
deger 1
deger 2
deger 3
2
tip-donusumu: 1 degerlendirme, 2 kullanim -> hemen
demet-elemani: 1 degerlendirme, 2 kullanim -> hemen
okunmayan-eleman: 1 degerlendirme, 0 kullanim -> hemen
hemen: 3
ilk-kullanimda: 0
her-kullanimda: 0
hic: 0
```

`ratio` yedinin ikiye bölümünü 3.5 olarak verir, çünkü bölme `Double` üzerinde yapıldı. `Int.max` en büyük `Int` değerini basar; bu değerin bir fazlası bir program hatasıdır ve dersin ölçümünden çıkarıldı. `0.1 + 0.2 == 0.3` beklentinin tersine `false` verir: toplama tam 0.3'ü değil, ona çok yakın bir sayıyı üretir. Kayan noktalı sayı ikilik tabanda tam gösterilemediği için eşitlik yerine fark ölçülür; bu bir Swift özelliği değil, `Double` temsilinin sonucudur.

Dönüşüm satırı bir kez, tanımlandığı satırda, ilk kullanımdan önce değerlendirildi: `tip-donusumu` iki kullanımla `hemen` çıktı. Demet elemanları ise soldan sağa değerlendirildi: `deger 1`, `deger 2`, `deger 3`. Demet (tuple), birden çok değeri tek bir değerde toplayan yapıdır; elemanlar tanım satırında hazır olur.

**DT16.** `Int.max` yazdırması yalnız 64 bitlik `Int` için geçerlidir; ölçümde kullanılan derleyici 64 bitlik bir hedef için derledi.

**DT17.** `0.1 + 0.2 == 0.3` iki sabit ifadeyle ölçüldü; hesabı yapan değerlendirmenin derleyicide mi koşumda mı yapıldığı bu derste ayırt edilmiyor.

## Sayısal Tip Başlatıcıları

Swift farklı sayısal tipler arasında örtük dönüşüm yapmaz; dönüşümü sen yazarsın. Bunun aracı tipin başlatıcısıdır: `Double(7)`, `Int(3.9)`, `UInt8(200)`. Ondalıklı bir değeri `Int` yapan başlatıcı kesirli kısmı atar, yani sıfıra doğru keser; `Int(3.9)` 3, `Int(-3.9)` ise -3 verir. Yuvarlama gerekiyorsa ayrı bir işlem yazarsın.

Bu davranışı ölçmek için aşağıdaki blok ondalıklı bir sayıyı bir `Probe` üzerinden üretir ve iki farklı başlatıcıdan geçirir. Başlatıcı ifadenin kendisidir; bu yüzden sayıyı üreten `eval` çağrısı başlatıcının argümanı içinde durur.

```swift
// Convert.swift — baslaticilarla donusum
let truncateProbe = Probe("kesme-donusumu")
let widenProbe = Probe("genisletme-donusumu")
let cut = Int(truncateProbe.eval(3.9))
let negativeCut = Int(truncateProbe.eval(-3.9))
let wide = Double(widenProbe.eval(7))
let small = UInt8(widenProbe.eval(200))
_ = truncateProbe.use { cut + negativeCut }
_ = truncateProbe.use { cut - negativeCut }
_ = widenProbe.use { wide }
_ = widenProbe.use { small }
print(cut, negativeCut, wide, small)
truncateProbe.report()
widenProbe.report()
```

```
3 -3 7.0 200
kesme-donusumu: 2 degerlendirme, 2 kullanim -> her-kullanimda
genisletme-donusumu: 2 degerlendirme, 2 kullanim -> her-kullanimda
```

`Int(3.9)` 3, `Int(-3.9)` -3 verdi; yani dönüşüm sıfıra doğru keser. `Double(7)` `7.0` yazıldı ve `UInt8(200)` 200 olarak kaldı. İki ölçüm satırı da iki değerlendirme gösterdi: her başlatıcı çağrısı argümanını bir kez değerlendirdi ve her `Probe` iki başlatıcıya bağlı olduğu için sayı ikiye çıktı. Bu yüzden iki satır da `her-kullanimda` okunur; sayı dönüşümün değil, ölçüm düzeneğinin eseridir.

Burada önemli olan başlatıcının hata verebildiği yerdir: `UInt8(300)` gibi bir değer bu tipe sığmaz ve program durur. Bu yüzden dönüşüm yazarken değerin hedef tipe sığdığını önceden bilmek gerekir. Ders bu durumu çalıştırmaz.

**DT18.** Dönüşümler yalnız tipe sığan değerlerle ölçüldü; sığmayan değerin durumu bu derste çalıştırılmaz, yalnız anlatılır.

## Taşma İşleçleri

Tam sayı tiplerinin sınırı vardır. `UInt8` değeri 0 ile 255 arasında kalır. Normal `+` işleci sonucu bu sınırın dışına taşırsa program durur. Swift bunun yanında taşmayı kabul eden işleçler de sunar: `&+`, `&-` ve `&*`. Bu işleçler sonucu tipin kapasitesine göre başa sarar. `&` öneki, taşmayı bilerek istediğini söylemenin yoludur; sessizce olmaz, işleci seçerek olur.

Aşağıdaki blok `UInt8` değerine bir fonksiyon içinde `&+` ile sayı ekler. Eklenen sayı bir `Probe` üzerinden geldiği için her çağrı bir değerlendirme sayılır. İlk çağrı 250 değerine 10 ekler ve sınırı aşar; ikinci çağrı güvenli bir değerle çalışır.

```swift
// Wrap.swift — tasma isleci basa sarar
func bump(_ value: UInt8, probe: Probe) -> UInt8 {
    value &+ probe.eval(10)
}
let wrapProbe = Probe("tasma-isleci")
print(wrapProbe.use { bump(250, probe: wrapProbe) })
print(wrapProbe.use { bump(1, probe: wrapProbe) })
let floor: UInt8 = 0
print(floor &- 1, UInt8.max)
wrapProbe.report()
```

```
4
11
255 255
tasma-isleci: 2 degerlendirme, 2 kullanim -> her-kullanimda
```

`250 &+ 10` 260 olmadı; sonuç 4 çıktı, çünkü 255'ten sonra sayım 0'a döndü. `1 &+ 10` ise normal 11 verdi. Üçüncü satırdaki `0 &- 1` değeri `UInt8.max` ile aynı olan 255 çıktı: sınırın altına inen sayı üst uca sarıldı. Ölçüm satırı iki değerlendirme gösteriyor: her `bump` çağrısı operandı bir kez değerlendirdi, bu yüzden an `her-kullanimda` olur.

Taşma işleçleri ölçülebilir, çünkü program durmaz. Normal `+` ile aynı taşma ise durdurur ve bu yüzden bu derste çalıştırılmaz. Hangisini seçeceğin niyetine bağlıdır: sarmayı istiyorsan `&+`, taşmanın hata olmasını istiyorsan `+` yaz.

**DT19.** Taşma işleci `UInt8` ile ölçüldü; işaretli tiplerin `&+` ile sarma davranışı bu derste ölçülmedi.

## Tip Takma Adı ve Sınırlar

Her sayısal tipin bir alt ve üst sınırı vardır ve tip bunları `min` ile `max` statik özellikleri olarak sunar: `Int8.min` -128, `Int8.max` 127, `UInt8.max` 255. Bir tipin sınırını bilmek taşma sorusunu yerinde yanıtlar. Kodda bir tipe başka bir ad vermek istediğinde `typealias` kullanırsın: `typealias Pixel = UInt8`. Takma ad yeni bir tip değildir; aynı tipin ikinci adıdır, sınırlarını ve davranışını aynen taşır.

Aşağıdaki blok `Pixel` takma adını tanımlar, onunla bir sabit bağlar ve sabitin tipini ve sınırlarını yazdırır. Sabit bir `Probe`'dan gelir ve iki kez okunur.

```swift
// Alias.swift — tip takma adi ayni tiptir
typealias Pixel = UInt8
let aliasProbe = Probe("takma-ad-sabiti")
let brightness: Pixel = aliasProbe.eval(200)
_ = aliasProbe.use { brightness }
_ = aliasProbe.use { brightness &+ 100 }
print(type(of: brightness), Pixel.max, Int8.min)
aliasProbe.report()
```

```
UInt8 255 -128
takma-ad-sabiti: 1 degerlendirme, 2 kullanim -> hemen
```

`type(of: brightness)` `UInt8` yazdı, yani takma ad yeni bir tip yaratmadı. `Pixel.max` 255, `Int8.min` ise -128 çıktı. `Probe` tek bir değerlendirme gösterdi ve sabit kullanımdan önce kurulduğu için an `hemen` oldu. Takma ad yalnız ad düzeyinde bir kolaylıktır; çalışma zamanında hiçbir şey eklemez.

Sınır özelliklerini bilmek, dönüşüm ve taşma kararlarının temelidir. Bir değerin sığıp sığmayacağını `max` ile karşılaştırarak önceden yoklayabilirsin; böylece sığmayan bir dönüşümü hiç çalıştırmazsın.

**DT20.** Sınır değerleri `UInt8` ve `Int8` ile gösterildi; diğer tam sayı tiplerinin sınırları bu dersin dışındadır.

## Ondalığı Tam Sayıya Çevirmek

Bir `Double` değerini `Int` yapmanın tek bir yolu yoktur ve üç yaygın yol farklı sonuç verir. `Int(value)` ondalık kısmı atar, yani sıfıra doğru keser. `value.rounded()` en yakın tam değere yuvarlar; tam ortadaki değerde sıfırdan uzağa gider. `value.rounded(.down)` ise daima küçük olana iner. Üçü de önce bir `Double` üretir ya da doğrudan `Int` verir; hangi yolu seçtiğin, negatif sayılarda sonucu değiştirir.

Aşağıdaki blok bir sayıyı üç yolla çevirir. Çevrilecek değer bir `Probe`'dan gelir ve fonksiyon pozitif ve negatif bir değerle çağrılır.

```swift
// Rounding.swift — ondaligi tam sayiya cevirmek
func convert(_ value: Double, probe: Probe) -> (Int, Int, Int) {
    let source = probe.eval(value)
    return (Int(source), Int(source.rounded()), Int(source.rounded(.down)))
}
let roundProbe = Probe("yuvarlama")
print(roundProbe.use { convert(2.5, probe: roundProbe) })
print(roundProbe.use { convert(-2.5, probe: roundProbe) })
roundProbe.report()
```

```
(2, 3, 2)
(-2, -3, -3)
yuvarlama: 2 degerlendirme, 2 kullanim -> her-kullanimda
```

Pozitif `2.5` için üç yol `(2, 3, 2)` verdi: kesme 2, en yakına yuvarlama 3, aşağı yuvarlama 2. Negatif `-2.5` için sonuç `(-2, -3, -3)` oldu. Kesme sıfıra doğru gittiği için `-2` verdi; en yakına yuvarlama tam ortada sıfırdan uzağa gittiği için `-3`; aşağı yuvarlama ise daima küçük olana indiği için yine `-3` verdi. Pozitif sayıda kesme ile aşağı yuvarlama aynı sonucu verir, negatif sayıda ayrılırlar. `Probe` iki çağrıya karşılık iki değerlendirme gösterdi, bu yüzden an `her-kullanimda` okunur.

Dönüşüm yolunu seçerken sorman gereken şey, negatif değerlerin de gelip gelmediğidir. Gelmiyorsa üç yolun ikisi aynı işi görür; geliyorsa her birinin kuralı ayrı bir karar demektir.

**DT21.** Yuvarlama `2.5` ve `-2.5` ile ölçüldü; diğer yuvarlama kuralları (`.up`, `.toNearestOrEven`) bu dersin dışındadır.

## Ondalık Eşitliği

İkili kayan nokta sayıları, onluk tabandaki bazı basit kesirleri tam olarak tutamaz. `0.1`, `0.2` ve `0.3` bunların en bilinenidir: her biri en yakın temsil edilebilir değere yuvarlanır. İki sayıyı toplayıp üçüncüyle `==` ile karşılaştırmak bu yüzden beklenmedik bir sonuç verebilir. Ondalık sayıları karşılaştırırken tam eşitlik yerine, kabul edilebilir bir fark sınırı seçersin.

Aşağıdaki blok bu durumu ölçer. Toplamın ilk terimi bir `Probe`'dan gelir. Blok toplamı, tam eşitlik sonucunu ve farkın küçük bir sınırın altında kalıp kalmadığını yazdırır.

```swift
// Equality.swift — ondalik esitligi
func sum(probe: Probe) -> Double {
    probe.eval(0.1) + 0.2
}
let equalProbe = Probe("ondalik-toplam")
let total = equalProbe.use { sum(probe: equalProbe) }
print(total)
print(total == 0.3)
print(abs(total - 0.3) < 0.000001)
equalProbe.report()
```

```
0.30000000000000004
false
true
ondalik-toplam: 1 degerlendirme, 1 kullanim -> ilk-kullanimda
```

Toplam `0.30000000000000004` yazdırdı, tam eşitlik `false` verdi, küçük sınırla yapılan karşılaştırma ise `true` çıktı. `0.1` ve `0.2` ikili tabanda tam yazılamadığı için toplamları `0.3` ile aynı değerde buluşmadı; fark son basamaktadır. Bu yüzden ondalık sayılarda `==`, hesaplanmış değerler için güvenilir bir sınama değildir. Ölçüm tek değerlendirme gösterdi: ilk terim `Probe`'dan bir kez alındı ve sonraki karşılaştırmalar yeniden hesaplamadı, an `ilk-kullanimda` olur.

Sınırın büyüklüğü işe göre seçilir; burada `0.000001` yeterli bir ölçüydü. Para gibi kuruşu önemli olan değerlerde ondalık tip yerine tam sayı birimleriyle çalışmak daha güvenlidir.

Yuvarlama kuralını sonuca bakarak değil, niyete göre seç. Parayı ya da sayacı aşağı kesmek istiyorsan `.down`, en yakın değeri istiyorsan `rounded()`, yalnız tam kısmı almak istiyorsan `Int(value)` yazarsın. Üçünü aynı sanmak, negatif değer ilk geldiği gün hatalı bir sonuca yol açar. Çevrilen `Double` tam sayı aralığının dışındaysa `Int(value)` programı durdurur; bu ders bu durumu çalıştırmaz.

Ondalık eşitlikte de aynı ilke geçerlidir: sonucu ne olması gerektiğine göre bir sınırla karşılaştır, tam eşitliğe güvenme. Sınırı bir isimli sabite almak, aynı ölçünün birden çok yerde tutarlı kalmasını sağlar.

**DT22.** Eşitlik `Double` ile ölçüldü; `Float` ve `Decimal` gibi tiplerde aynı toplamın sonucu bu dersin dışındadır.

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

`okunmayan-eleman` satırına bak: demet içinde bir eleman tanımlandı, bir kez değerlendirildi, hiç okunmadı. Kural `hemen` der, çünkü değerlendirme kullanımdan önce yapıldı ve hiç kullanım yoktu. Yani demet elemanı okunmasa da değerlendirilir; `hic` yalnızca ifade hiç değerlendirilmediğinde ortaya çıkar. Bu satır, ölçüm koşulunun neden "en az iki kullanım" istediğini de gösterir: sıfır kullanımda kural, boşa değerlendirilen bir ifadeyi gerçek bir `hemen`'den ayıramaz.

**DT23.** Sıfır kullanım bu satırda bilerek bırakıldı; derste başka hiçbir gözlem sıfır kullanım taşımaz.

## Özet

- `Int`, `Double`, `Bool` ve `String` dört temel tiptir; tipler kendiliğinden karıştırılmaz.
- Dönüşüm açıktır: `Double(count)` bir ifadedir ve tanımlandığı satırda değerlendirilir.
- `0.1 + 0.2 == 0.3` kayan noktalı gösterim yüzünden `false` verir.
- Demet elemanları soldan sağa ve okunmasa da değerlendirilir.
- Bu dersin anı: **hemen** (dönüşüm ifadesi `let` satırında bir kez).

## Sonraki Adım

`String` bu derste yalnız adıyla geçti. Bir sonraki ders dizgiye iniyor: bir karakter nedir, `count` ile `utf8.count` neden ayrışır ve dizgi içine yerleştirilen ifade kaç kez kuruluyor?
