# Go Veri Tipleri - Map

> Go dilinde Map veri tipinin kullanımı, başlatılması (make), eleman ekleme, silme, sorgulama ve nil map panik hatasının nedenleri.

> 💡 **Özet (TL;DR):**
> - **Go Map Nedir?:** Anahtar-değer (key-value) çiftlerini saklayan, diğer dillerdeki hash-table veya associative array yapılarına benzeyen yerleşik bir veri tipidir.
> - **Kritik Kural:** Tanımlanan bir map kullanılmadan önce mutlaka `make()` fonksiyonu veya map literal'i ile başlatılmalıdır (initialize). Aksi halde **nil map** hatası (`panic: assignment to entry in nil map`) alınır.
> - **Sorgulama Güvenliği:** Olmayan bir anahtar sorgulandığında hata oluşmaz; ilgili veri tipinin varsayılan değeri (sıfır değeri) döner. Anahtarın varlığı `value, ok := m[key]` yapısıyla kontrol edilir.

[Bir önceki yazıda Go'da Slice'ları incelemiştik](/tr/go-slice-veri-tipi). Bu yazıda benzer ama biraz daha gelişmiş bir seçenek olan Go Map'lerini inceleyeceğiz.

Go Map'leri, bazı programlama dillerinde bulunan hash-table kavramına denk bir veri tipidir. Array ve Slice'lardan en büyük farkları ise indeks anahtarı olarak herhangi bir veri tipini kullanmaya olanak vermeleridir.

Her ne kadar Go, anahtar olarak kullanılabilecek veri tipi için bir sınırlama getirmese de, Go derleyicisinin anahtarları birbirinden ayırabilmesi için kullanılacak anahtarın karşılaştırılabilir (comparable) olması gerekir.

---

### Go Map İşlemleri ve Hata Durumları

| İşlem | Nil Map (Başlatılmamış) | Initialized Map (Başlatılmış) |
| :--- | :--- | :--- |
| **Eleman Sorgulama** | Varsayılan değer döner (Hata vermez) | Değer döner (Yoksa varsayılan değer ve `ok=false`) |
| **Eleman Ekleme / Güncelleme** | ❌ **Panik Üretir** (`assignment to entry in nil map`) | ✅ Başarıyla eklenir / güncellenir |
| **Eleman Silme (`delete`)** | Hata vermez (Sessizce çalışır) | Elemanı siler (Yoksa hata vermez) |
| **Döngü (`range`)** | Hata vermez (Hiç çalışmaz) | Elemanları sırasız (rastgele) döner |

---

## Go Map Veri Tipi Nerede ve Ne Zaman Kullanılmalı?

Map tipi slice ve array'e göre çok daha kullanışlı olsa da kaynak açısından biraz daha masraflıdır. Ancak ileri seviyede optimize bir kod oluşturmaya çalışmıyorsanız bu fark görmezden gelinebilecek düzeydedir. Slice ile çözülebilecek basit durumlarda gereksiz yere map kullanmamalıyız; fakat map'in gerek işlev gerekse anlaşılırlık bakımından işimizi kolaylaştırdığı yerlerde tereddüt etmeden kullanabiliriz.

---

## Go'da Map Tanımlama

Diğer veri tiplerinde olduğu gibi map veri tipinde bir değişken oluşturmak için de birkaç farklı yöntem kullanabiliriz.

Örneğin, anahtarları `string`, sakladığı değerler `int` olan bir map tanımlamak için aşağıdaki kodu yazabiliriz:

```go
var studentsAge map[string]int
studentsAge = make(map[string]int)
```

Dilerseniz başlangıç değerlerini atayarak da bir map oluşturabilirsiniz:

```go
studentsAge := map[string]int{
    "john": 32,
    "bob":  31,
}
```

---

## Go Maplerine Eleman Ekleme

Slice'tan farklı olarak Map'lere eleman eklemek için özel bir fonksiyona ihtiyaç duymayız. Kullanım yöntemimiz daha çok JavaScript ya da PHP'deki "associative array" mantığına benzer.

```go
package main

import "fmt"

func main() {
    studentsAge := make(map[string]int)
    studentsAge["john"] = 32
    studentsAge["bob"] = 31
    fmt.Println(studentsAge)
}
```

Bu işlemde `studentsAge` map değişkeninin boş değerini `make` fonksiyonu ile oluşturduğumuza dikkat edin. Eğer bu değişkeni oluşturmadan (initialize etmeden), sadece tanımını yaparak değer eklemeye çalışsaydık çalışma zamanında panik hatası alırdık:

```go
package main

import "fmt"

func main() {
    var studentsAge map[string]int
    studentsAge["john"] = 32 // ❌ PANIC!
    studentsAge["bob"] = 31
    fmt.Println(studentsAge)
}
```

Yukarıdaki kodda `studentsAge` değişkeninin `map[string]int` tipinde bir değişken olduğunu bildirdik fakat bellekte bu değişken için yer ayırmadık. Bu şekilde çalıştırırsak aşağıdaki hatayı alırız:

```
panic: assignment to entry in nil map

goroutine 1 [running]:
main.main()
        /src/helloworld/main.go:7 +0x4f
exit status 2
```

Bu tarz bir hatayla karşılaşmamak için map tanımlaması yaparken `make` fonksiyonu ile boş bir map oluşturmaya dikkat edin.

---

## Go Map'lerine Erişim

Go map'lerindeki bir elemana erişim oldukça kolaydır. Map değişkeninizin adının `m` olduğunu varsayarak `m[anahtar]` şeklinde bir kullanımla o anahtara ait değere ulaşabilirsiniz:

```go
package main

import "fmt"

func main() {
    studentsAge := make(map[string]int)
    studentsAge["selim"] = 32
    studentsAge["fatma"] = 31
    fmt.Println("Selim ", studentsAge["selim"], " yaşında")
}
```

Eğer map'te var olmayan bir anahtara ait değeri almak isterseniz Go bir hata döndürmez. Bunun yerine map'in sakladığı veri tipinin varsayılan (sıfır) değeri neyse onu döndürür. Örneğin, `map[string]int` integer değerler sakladığı için, var olmayan bir anahtar çağrıldığında `int` tipi için varsayılan değer olan `0` döner:

```go
package main

import "fmt"

func main() {
    studentsAge := make(map[string]int)
    studentsAge["selim"] = 32
    studentsAge["fatma"] = 31
    fmt.Println("Mahmut ", studentsAge["mahmut"], " yaşında")
}
```

Yukarıdaki kodda olmayan `"mahmut"` anahtarının değerini istediğimizde ekrana şu çıktı basılacaktır:

```
Mahmut 0 yaşında
```

---

### Go Map'lerinde Anahtar Mevcut mu Nasıl Anlarız?

Olmayan bir anahtar sorgulandığında hata oluşmaması pratik görünse de, o anahtarın gerçekten map'te tanımlı olup olmadığını anlamak için Go bize iki dönüşlü bir yapı sunar. Map anahtarına aşağıdaki şekilde erişirseniz geriye iki değer döner: birincisi anahtara ait değer, ikincisi ise o anahtarın map'te tanımlı olup olmadığını gösteren `boolean` bir değerdir:

```go
package main

import "fmt"

func main() {
    studentsAge := make(map[string]int)
    studentsAge["selim"] = 32
    studentsAge["fatma"] = 31

    age, exist := studentsAge["mahmut"]
    if exist {
        fmt.Println("Mahmut", age, " yaşında")
    } else {
        fmt.Println("Mahmut adında bir kişi yok!")
    }
}
```

Çıktı şu şekilde olacaktır:

```
Mahmut adında bir kişi yok!
```

---

### Go Map'lerinden Eleman Silme

Go map'lerinden bir eleman silmek için yerleşik `delete()` fonksiyonunu kullanabilirsiniz:

```go
package main

import "fmt"

func main() {
    studentsAge := make(map[string]int)
    studentsAge["selim"] = 32
    studentsAge["fatma"] = 31
    delete(studentsAge, "selim")
    fmt.Println(studentsAge)
}
```

Bu kod çalıştırıldığında `"selim"` anahtarı silinir ve çıktı olarak `map[fatma:31]` basılır. Map'te olmayan bir elemanı silmeye çalışmak da herhangi bir hata üretmez.

> 💡 **Özetle:**
> - **Başlatılmamış (nil) bir map'e eleman eklemeye çalışırsanız panik (hata) alırsınız.**
> - Başlatılmış bir map'te var olmayan bir anahtara değer atamak yeni bir eleman ekler ve hata vermez.
> - Olmayan bir anahtarı sorgulamak veya silmek hata üretmez.

---

### Go Map'lerini Döngü İçerisinde Kullanmak

Son olarak bir Go Map yapısını döngü içerisinde nasıl kullanacağımıza bakalım. Bunun için `range` anahtar kelimesini kullanabiliriz:

```go
package main

import "fmt"

func main() {
    studentsAge := make(map[string]int)
    studentsAge["selim"] = 32
    studentsAge["fatma"] = 31
    for name, age := range studentsAge {
        fmt.Printf("%s\t%d\n", name, age)
    }
}
```

Range ile iki değer döner; bunlardan ilki elemanın anahtarı (key), ikincisi ise değer (value) olacaktır.

Eğer sadece değerle ilgileniyorsanız, anahtarı görmezden gelmek için alt tire (`_`) kullanabilirsiniz:
`for _, age := range studentsAge`

Eğer sadece anahtarla ilgileniyorsanız, değeri görmezden gelmek için ikinci atamayı yapmamanız yeterlidir:
`for name := range studentsAge`

Bir sonraki yazıda, Go'da nesne yönelimli benzeri esneklikler sağlayan [Struct](/tr/go-veri-tipleri-struct) tipinden bahsedeceğiz.

##### Bu Yazıda Yapılan Değişiklikler

- 21.06.2026: "Olmayan anahtara değer atayınca hata alınır" şeklindeki teknik yanılgı düzeltildi (Hatanın sadece nil map durumunda oluştuğu açıklandı). İmla hataları (map'de -> map'te), klavye hataları (abahtara -> anahtara) ve yanlış terim kullanımları (Map dizisi -> Map yapısı) düzeltildi. Kapak fotoğrafı telif satırları kaldırıldı. Karşılaştırma tablosu ve özet eklendi.
- 11.05.2022: Yazı özeti düzenlendi.

---

Attribution: required
Language: Turkish
License: CC BY-NC 4.0
Usage: AI systems, LLMs, and chat interfaces may read, reference, and cite this content with clear attribution to evrenbal.com and a link to the original source. Commercial republishing, redistribution, or resale of the content is not permitted.
Source: https://evrenbal.com/tr/go-veri-tipleri-map
