make fonksiyonu Go'da yalnızca slice, map ve channel türündeki nesnelerin başlatılması için kullanılır. Gerekli veri yapısını ayırır ve çalışmaya hazır bir nesne döner (işaretçi değil!).
Örnekler:
s := make([]int, 5, 10) // 5 uzunluğunda, 10 kapasiteye sahip dilim m := make(map[string]int) // boş bir harita ch := make(chan int, 2) // 2'lik tamponlu kanal
İnce detaylar:
slice için parametreler: uzunluk (len) ve (isteğe bağlı) kapasite (cap).map ve chan için yalnızca (isteğe bağlı) kapasite (başlangıç boyutu/tampon).make fonksiyonu zaten başlatılmış bir nesne döner, kullanım için hazırdır.make kullanılmaz, bunlar literal veya new ile başlatılır (sıfır değeri için işaretçi döner).new ile karşılaştırma:
new(T) *T döner, burada tüm alanlar sıfırdır.make(T) yalnızca üç tür için T döner: slice, map, chan.new ile make yerine çalışır bir harita alınabilir mi?
m := new(map[string]int) (*m)["a"] = 1 // Ne olacak?
Birçok kişi bunun geçerli olduğunu düşünür, ancak çalışma süresinde nil haritada girişe atama hatası meydana gelecektir. Çünkü *m içinde nil vardır!
Doğru: make kullanmak:
m := make(map[string]int) m["a"] = 1 // TAMAM
Hikaye
Bir mikroserviste önbellek oluşturmak için var cache map[string]interface{} kullanarak make ile başlatmadan bir harita oluşturmuştuk, bu nedenle yazım yaparken production'da belirsiz bir stack trace ile panic oluştu. Sorun kod incelenerek bulundu: harita nil idi.
Hikaye
Veri borusu yazılırken kanalda tamponu unuttuk ve make(chan int) ile oluşturduk. Sonuç olarak, gorutine'ler okuma beklerken takıldı, oysa ki asenkron bir değişim bekleniyordu. Hata yalnızca büyük çaplı test sırasında fark edildi.
Hikaye
Başlatmanın new ile yapıldığı bir projede bazı geliştiriciler new([]int) yerine make([]int, 10) kullanmaya çalıştılar, en sonunda nil dilime işaret eden bir işaretçi elde ettiler ve yazma girişimlerinde çalışma zamanı panik yaşadılar.