Go Veri Tipleri - Map

Sayfayı kopyala
💡 Ö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. 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:
var studentsAge map[string]int
studentsAge = make(map[string]int)
Dilerseniz başlangıç değerlerini atayarak da bir map oluşturabilirsiniz:
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.
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:
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:
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:
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:
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:
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:
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 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.
