---
title: 'Temel Tipler'
source: 'https://academia.sh/tr/kurslar/go-temelleri/temel-tipler'
course: 'Go Temelleri'
language: tr
updated: '2026-08-23T14:25:00+00:00'
license: 'CC BY-SA 4.0'
---

# Temel Tipler

Dört yazılmamışlık aynı çerçeveden geçiriliyor: tipsiz bir sabitin varsayılan tipi int oluyor, int8 sınırını aşan bir toplam -128'e sarıyor, çalışma zamanında toplanan iki float64 değeri 0.3'e eşit çıkmıyor, ve bir karakter değişmezinin tipi aslında int32 — rune yalnız bir takma ad. Sınırlayıcı ölçüm: örtük dönüşümün reddi sabitlerde geçerli değil.

Önceki ders bir değişkenin tipini hep bir değerden çıkardı, ama tiplerin kendileri hiç
sorgulanmadı. Bu ders dört soruyu birden soruyor: bağlam vermeden yazılan bir sayının
varsayılan tipi ne, bir tam sayı sınırını aştığında ne oluyor, iki kayan noktalı değer
toplanıp karşılaştırıldığında beklediğimiz sonucu veriyor mu, ve `rune` dediğimiz tip aslında
nedir? Dördü de aynı üç sınıfla okunuyor — tanımlı, reddedildi, açıkta — ama bu dördü, kursun
merkezî on beş kalemlik çerçevesinin parçası değil; bu dersin kendi gözlemi.

Programlama Temelleri kursu (M01/K02) temel veri tiplerini, işleç önceliğini ve açık ile örtük
dönüşümü Python'la kurdu. **Bu kavramlar burada tekrar kurulmaz** — farkı tek cümleyle yazmak
yeter: orada tipler çalışma zamanında esnekti ve bir değer taştığında sonuç büyük tam sayıya
genişliyordu; Go'da her tam sayı tipi **sabit genişliktedir** ve taşma genişlemeyle değil,
sarmayla karşılanıyor. Bu ders, o genişliğin sınırında ne olduğunu ölçüyor.

## Dört Yazılmamışlık, Tek Çerçeve

```go
// temel.go — dort yazilmamislik: varsayilan tip, tasma, kayan nokta karsilastirmasi, rune
package main

import "fmt"

const Sayi = 5

func main() {
	fmt.Printf("%-28s tip=%-8s deger=%v\n", "tipsiz sabitin varsayilani", fmt.Sprintf("%T", Sayi), Sayi)

	var b int8 = 127
	b++
	fmt.Printf("%-28s tip=%-8s deger=%v\n", "tam sayi tasmasi", fmt.Sprintf("%T", b), b)

	var x, y float64 = 0.1, 0.2
	toplam := x + y
	fmt.Printf("%-28s esit_mi=%-6v toplam=%v\n", "kayan nokta karsilastirmasi", toplam == 0.3, toplam)

	c := 'A'
	fmt.Printf("%-28s tip=%-8s deger=%v\n", "karakter degismezi", fmt.Sprintf("%T", c), c)
}
```

```
tipsiz sabitin varsayilani   tip=int      deger=5
tam sayi tasmasi             tip=int8     deger=-128
kayan nokta karsilastirmasi  esit_mi=false  toplam=0.30000000000000004
karakter degismezi           tip=int32    deger=65
```

**DT10.** Dört satır da aynı üç sınıfla (tanımlı, reddedildi, açıkta) okunuyor, ama bu on beş
kalemlik çekirdeğin bir parçası değil — ortak çerçeveye eklenen yeni bir gözlem. Sıfır Değerler
dersindeki 8/4/3 dağılımı bu dört satırı içermiyor.

Dört satırın üçü **tanımlı**, biri **açıkta**. Hiçbiri **reddedilmiyor** — dördü de geçerli
Go kaynağıdır, dördü de derlenir ve çalışır; aralarındaki fark, sonucun kaynaktan mı, sabit bir
kuraldan mı, yoksa çalışma zamanındaki temsilden mi geldiğidir. Sırayla okuyalım.

## Tipsiz Sabitin Varsayılan Tipi

`Sayi` sabiti `5` değeriyle tanımlanırken hiçbir tip yazılmıyor — `const Sayi = 5`, `const Sayi
int = 5` değil. Go'da böyle bir sabit **tipsizdir**: kendi başına bir `int`, bir `float64` ya
da başka bir tip değildir, yalnız bir sayı değeridir ve kullanıldığı yere göre biçimlenir. `Sayi`
`fmt.Printf`e bir `interface{}` argümanı olarak geçtiğinde, biçimlenecek somut bir tipe ihtiyaç
duyuluyor ve derleyici burada tipsiz sabitin **varsayılan tipini** devreye sokuyor: tam sayı
sabitleri için bu varsayılan `int`tir.

Bu, önceki derste ölçülen kısa bildirimden farklı bir mekanizma. Kısa bildirimde tip, atanan
değerin **kendi** tipinden çıkarılıyordu; burada değerin başlangıçta hiç tipi yok, tip yalnız
bir bağlam onu zorladığında beliriyor. `Sayi`yı bir `float64` değişkenine atasaydık, aynı sabit
hiç dönüşüm yazmadan `float64` olurdu — çünkü tipsiz bir sabit, hedefin izin verdiği her tipe
**kendiliğinden** uyar. Bu ayrım, dersin sınırlayıcı ölçümünde tekrar karşımıza çıkacak.

Varsayılan tip yalnız `int` ile sınırlı değil; her sabit türünün kendi varsayılanı var. Tırnak
içindeki bir sabit varsayılan olarak `string`, `true`/`false` varsayılan olarak `bool`, ondalık
yazılan bir sabit varsayılan olarak `float64` alır. Bunların hiçbiri kaynakta yazılmıyor —
önceki derste kısa bildirimin bir **değerden** tip çıkardığını görmüştük; burada görülen,
değerin kendisinin de, hiçbir bağlam onu zorlamadığı sürece, kendi başına **tipsiz** kalmasıdır.
Tip, ancak bir yere yerleştirildiğinde ortaya çıkıyor.

## Tam Sayı Taşması: Tanımlı Bir Sarma

`int8` tipi 8 bit genişliğindedir ve işaretli olduğu için -128 ile 127 arasındaki değerleri
tutar. `b`ye 127 verip bir arttırdığımızda, sonuç bu aralığın dışına taşıyor — ama program
çökmüyor, bir hata da üretmiyor. Sonuç **-128** oluyor: sarma, aralığın üst ucundan alt ucuna
dönüyor.

**DT11.** Taşma burada kasıtlı üretiliyor. Go, tam sayı taşmasını bir hata saymıyor; ikiye
tümleyen aritmetiğiyle **tanımlı** bir şekilde sarıyor. Bu, "yazılmayanın karşılığı" sorusuna
üçüncü bir yanıt daha ekliyor: taşmayı önleyecek bir denetim yazılmadı, ama dil bu boşluğa
rastgele bir değer değil, aritmetik olarak öngörülebilir bir değer koyuyor.

Sarmanın kuralı basit: `int8`in üst sınırını (127) bir aşan değer, alt sınırdan (-128) devam
eder. Bu, ikiye tümleyen gösterimin doğal bir sonucu — aynı bit örüntüsü, işaretli okunduğunda
negatif, işaretsiz okunduğunda pozitif bir sayıya karşılık gelir ve toplama işlemi bit
düzeyinde aynı kalır, yalnız yorumlanışı değişir. Derleyicinin burada hiçbir denetim eklememesi
bir ihmal değil — sarma davranışı, donanımın zaten yaptığı bir işlemi olduğu gibi görünür
kılıyor.

Sarmanın öngörülebilir olması, onu **güvenli** yapmıyor. `-128` sonucu, `b`nin gerçek matematik
değerinin (128) hiçbir yaklaşık hâli değil, tamamen farklı bir sayı — üstelik işareti de
değişmiş. Bir hesaplama bu sınırı fark etmeden geçerse, sonucun **yanlış** olduğu hiçbir yerde
işaretlenmez; taşma, ilk derste ölçülen reddedilme ailesinden değil, ölçüm çekirdeğinin
tanımladığı `tanımlı` sınıfından. Dil bir şey koyuyor, ama koyduğu şey her zaman aritmetik
olarak beklenen şey değil.

Bu davranış, tam sayı tiplerinin genişliğinin neden kaynakta **açıkça** seçilmesi gerektiğini
gösteriyor. `int8` yerine daha geniş bir tip (`int32`, `int64`) seçilseydi aynı toplama hiçbir
sarma üretmezdi; sarma, değerin kendisinden değil, seçilen genişlikten kaynaklanıyor. Bu da
tam sayı tipini seçmenin, önceki derste ölçülen kısa bildirimin **dışında** kalan bir karar
olduğunu gösteriyor — kısa bildirim `b := int8(127)` yazılmadıkça hiçbir zaman `int8`e varmaz,
varsayılan olarak her zaman `int`e düşer. `int8` gibi dar bir tip yalnız `var` ile ya da açık
bir dönüşümle seçilebiliyor, ve bu seçim taşma sınırını da beraberinde getiriyor.

## Kayan Nokta Karşılaştırması: Açıkta Kalan Sonuç

Üçüncü satır, `x` ve `y` adlı iki `float64` değişkenini `0.1` ve `0.2` ile ilklendirip
topluyor ve toplamı `0.3`e eşitliyor. Sonuç `false`. Toplamın kendisi de `0.3` değil,
`0.30000000000000004`.

**DT12.** Burada yazdırılan ondalık basamaklar bir ortama bağlı veri değildir — bu, IEEE 754
ikili kesirli gösteriminin **belirlenimci** sonucudur ve her koşumda aynı basamaklara varır.
`0.1` ve `0.2` ikilik tabanda sonlu bir kesir olarak yazılamaz, tıpkı `1/3`ün onluk tabanda
yazılamaması gibi; her ikisi de en yakın `float64` değerine yuvarlanır ve toplamları, gerçek
matematiksel toplamın kendisi değil, o iki yuvarlanmış değerin toplamıdır. Bu yuvarlama Go'ya
özgü değil — `float64` temsili dilin belirtimi değil, IEEE 754 standardının kendisi ve dil bu
temsili olduğu gibi devralıyor.

Bu satır **açıkta** sınıfına giriyor, çünkü dil burada hiçbir şey koymuyor ve derleyici de
hiçbir şeyi reddetmiyor. `==` işleci geçerli bir karşılaştırmadır, derlenir ve çalışır; yalnız
sonucun "matematiksel olarak beklenen" olup olmadığı çalışma zamanındaki temsile bağlı kalıyor.
Kod, ne yaptığını söylüyor — iki `float64` değerini eşitliyor — ama okuyanın kafasındaki
"0.1 artı 0.2, 0.3 eder" beklentisiyle örtüşüp örtüşmeyeceğini önceden söylemiyor.

Burada ilginç bir ayrıntı var: `Sayi` sabitinde gördüğümüz tipsiz sabit mekanizması, bu satırı
da etkileyebilirdi. `0.1 + 0.2 == 0.3` ifadesi, üç tarafı da tipsiz sabit olarak yazılsaydı,
derleyici bu toplamı **derleme zamanında**, keyfi hassasiyetle hesaplardı ve sonuç gerçekten
`true` çıkardı — çünkü sabit aritmetiği ikili yuvarlamaya değil, tam kesir hesabına dayanıyor.
Açıkta kalan davranış, sabitlerin değil, **çalışma zamanı değişkenlerinin** özelliği: `x` ve
`y` birer değişken olduğu için toplamaları çalışma zamanında, önceden yuvarlanmış ikili
değerlerle yapılıyor.

## Karakterin Tam Sayı Olması

Dördüncü satırda `c := 'A'` yazılıyor. Tek tırnak içindeki bir karakter, Go'da bir **rune
değişmezidir** ve kısa bildirimle tipi çıkarıldığında `int32` çıkıyor — `rune` diye ayrı bir
tip görünmüyor, çünkü `rune`, dilin belirtiminde `int32`nin bir **takma adından** başka bir
şey değil. `%T` her ikisini de aynı adla, `int32` diye yazdırıyor.

Değerin kendisi de bunu doğruluyor: çıktıda `deger=65` yazıyor, `A` değil. `fmt.Printf`in
`%v` biçim doğrulayıcısı, bir değeri kendi tipine göre yazdırıyor ve `int32`nin varsayılan
yazımı ondalık bir sayıdır — karakteri görmek isteseydik `%c` yazmamız gerekirdi. Bu, "rune bir
tam sayıdır" iddiasının yalnız tip sisteminde değil, biçimlendirmede de göründüğü anlamına
geliyor: dil, bir `rune`u özel bir "karakter" kutusunda tutmuyor, sıradan bir sayı gibi
davranıyor ve okunabilir bir karakter olarak görünmesi tamamen biçimlendirme çağrısının
tercihi.

Bu dördüncü satır ilk satırla aynı aileden: ikisi de bir değişmezin **varsayılan tipini**
ölçüyor. Aradaki fark, ilkinde varsayılan tip `int`ken, karakter değişmezinde varsayılan tipin
doğrudan `rune`un kendisi (`int32`) olması. `'A'` yazıldığında dil, bunun bir kod noktası
olduğunu ve kod noktalarının tam sayı olarak temsil edildiğini biliyor; `65` yazmakla `'A'`
yazmak arasındaki fark bu yüzden yalnız **okunurlüktedir** — ikisi de aynı tipte, aynı değerde
sonuçlanıyor.

Bu, `rune` sözcüğünün neden bu kursta hiç çevrilmediğini de açıklıyor: `rune`, Go'nun kendi
anahtar sözcüklerinden biri değil, standart kitaplığın tanımladığı bir **tip takma adıdır** —
tıpkı `byte`ın `uint8`in takma adı olması gibi. Bir takma ad, kaynakta yazıldığında derleyici
tarafından **hemen** gerçek adına çözülüyor; çalışma zamanında `rune` diye ayrı bir tip
etiketi taşınmıyor, `%T` bunu doğruluyor. Bu ders boyunca "karakter" sözcüğünü ölçülmüş bir
şey için kullanmaktan kaçınıyoruz, çünkü tam olarak ölçtüğümüz şey, bir karakterin aslında bir
tam sayı olduğudur — kursun bileşik tipler konusundaki Dizgiler ve Rune'lar dersinde bu ayrım,
bir dizginin neden karakter değil bayt dizisi olduğuyla birlikte derinleşecek.

## Sınırlayıcı Ölçüm: Örtük Dönüşümün Reddi Sabitlerde Geçerli Değil

İlk derste ölçülen dört retten biri, örtük tip dönüşümünün reddiydi: bir `int32` değişkeni bir
`int64` değişkenine dönüşüm yazılmadan atanamıyordu. Bu kural, **tipsiz sabitler** için
geçerli değil. Ölçmek için ilk dersteki derleyici çağrısına dönüyoruz.

```go
// derleyici.go — derleyiciyi program icinden cagiran yardimci
package main

import (
	"os"
	"os/exec"
	"path/filepath"
)

func derlenirMi(kaynak string) bool {
	dizin, err := os.MkdirTemp("", "sinama")
	if err != nil {
		return false
	}
	defer os.RemoveAll(dizin)
	os.WriteFile(filepath.Join(dizin, "go.mod"), []byte("module sinama\n\ngo 1.24\n"), 0o644)
	os.WriteFile(filepath.Join(dizin, "kod.go"), []byte(kaynak), 0o644)
	cmd := exec.Command("go", "build", "./...")
	cmd.Dir = dizin
	cmd.Env = append(os.Environ(), "GOTOOLCHAIN=local")
	return cmd.Run() == nil
}

func sinif(ok bool) string {
	if ok {
		return "derlendi"
	}
	return "derlenmedi"
}
```

```go
// sinirlayici.go — ortuk donusumun reddi sabitlerde gecerli degil
package main

import "fmt"

func main() {
	sabitUyum := `package sinama
func F() { var hedef int64 = 5; _ = hedef }`
	degiskenUyumsuzlugu := `package sinama
func F() { var kaynak int32 = 5; var hedef int64 = kaynak; _ = hedef }`

	fmt.Printf("%-32s %s\n", "tipsiz sabit hedefe uyuyor", sinif(derlenirMi(sabitUyum)))
	fmt.Printf("%-32s %s\n", "ayni degeri tasiyan degisken", sinif(derlenirMi(degiskenUyumsuzlugu)))
}
```

```
tipsiz sabit hedefe uyuyor       derlendi
ayni degeri tasiyan degisken     derlenmedi
```

İki satır da aynı sayısal değeri (`5`) taşıyor ve aynı hedef tipe (`int64`) atanıyor. Birinci
satırda kaynak bir **tipsiz sabittir** — `5` yazımı hiçbir tipe bağlı değil, `int64`e doğrudan
sığar ve derleyici bunu bir dönüşüm değil bir ilk değer ataması sayıyor. İkinci satırda aynı
`5` değeri önce bir `int32` değişkenine atanıyor; bu noktadan sonra `5` artık tipsiz değil,
**`int32` tipinde somutlaşmış** bir değerdir ve `int64`e geçişi ilk derste ölçülen örtük
dönüşüm reddine takılıyor.

Bu, "aynı değer" ile "aynı tip" arasındaki farkı gösteriyor. Derleyicinin ret kararı, taşınan
sayısal değere değil, kaynağın **tipine** bakıyor. Bir tipsiz sabit, somutlaşana kadar hiçbir
genişlik taşımaz; bir değişken ise tanımlandığı anda belirli bir genişliğe kilitlenir. İlk
derste ölçülen kural bu yüzden yeniden yazılmalı: örtük dönüşüm, iki **tipli** değer arasında
reddediliyor; tipsiz bir sabitin hedefe uyması dönüşüm değil, sabitin doğasının bir sonucu.

Bu sınır, dördü olsaydı diye bir soruyla da sınanabilir: `5` yerine `500` yazıp hedefi `int8`
yapsaydık ne olurdu? O durumda tipsiz sabit hedefe **sığmadığı** için derleme yine reddederdi
— ama bu, bir dönüşüm reddi değil, bir **taşma reddidir**: derleyici, bir sabitin değerini
derleme zamanında bildiği için, hedefe sığmayacağını önceden görüp kaynağı hiç derlemez. Bu,
ikinci bölümde ölçülen çalışma zamanı taşmasından (int8'in 127'yi aşması) tamamen farklı bir
mekanizma: orada taşma çalışırken **sarıyordu**, burada taşma derlenirken **reddediliyor**,
çünkü sabitin değeri kaynakta zaten yazılı ve derleyici onu hesaplamak için programı
çalıştırmasına gerek yok.

Dört ölçüm de aynı ayrımı farklı açılardan gösteriyor: bir sabitin tipi kaynakta yazılmadığı
sürece **askıda** kalır ve ancak bir bağlam onu somutlaştırdığında kesinleşir; bir değişkenin
tipi ise tanımlandığı anda kesinleşir ve o andan sonra genişliğiyle birlikte taşınır. İlk
satırdaki varsayılan tip, dördüncü satırdaki karakterin tam sayı oluşu ve sınırlayıcı ölçümdeki
sabit-değişken ayrımı — üçü de bu askıda kalma durumunun farklı görünümleri. Yalnız ikinci ve
üçüncü satır bu aileden ayrılıyor: onlar askıda kalmayla değil, zaten somutlaşmış bir tipin
sınırlarıyla (`int8`in genişliği, `float64`ün ikilik temsili) ilgili.

## Özet

- Tipsiz bir tam sayı sabitinin bağlam vermeyen bir kullanımda varsayılan tipi `int`tir.
- `int8` sınırını aşan bir toplama, hata üretmeden -128'e sarıyor — taşma tanımlı, ama
  aritmetik olarak beklenen değil.
- Çalışma zamanında toplanan iki `float64` değeri, matematiksel olarak eşit görünen bir
  sabitle karşılaştırıldığında `false` verebiliyor; bu sonuç açıkta kalıyor.
- `rune`, `int32`nin bir takma adıdır; bir karakter değişmezinin varsayılan tipi doğrudan
  budur.
- Örtük tip dönüşümünün reddi yalnız tipli değerler arasında geçerli — tipsiz bir sabit,
  hedef tipe kendiliğinden uyuyor.

## Sonraki Adım

Bu derste ölçülen dört yazılmamışlığın üçü tanımlı bir karşılık buldu, biri açıkta kaldı. Ama
hiçbiri, bir değişkenin **hiç** değer almadığı durumu sormadı — `var b int8` yazıp hiç değer
vermeseydik, `b` ne olurdu? Sıradaki ders bu soruyu kursun merkezine taşıyor: on beş ayrı
yazılmamışlığı tek bir çerçevede topluyor ve sekizinin tanımlı, dördünün reddedilmiş, üçünün
açıkta olduğunu ölçüyor.
