Soru tarihi:
Go'da varsayılan olarak generic map türünde evrensel konteyner yoktur — yalnızca Go 1.18 ile birlikte genel türler ortaya çıkmıştır, ancak dinamik yapılar için daha önce ve şimdi sıklıkla map[string]interface{} kullanılır, bu da bir dize anahtarı ile her tür değeri saklamayı sağlar.
Sorun:
Bu desen, her yerde dizin/JSON nesnesinin bir eşdeğeridir ve serileştirme, middleware çalışması, belirli bir yapıya sahip olmayan veriler (örneğin, encoding/json ile JSON ayrıştırıcı) için sıklıkla kullanılır. Ancak, değerlere erişim, türlerin manuel olarak dönüştürülmesini ve örtük değerler ile anahtar eksikliklerine dikkat edilmesini gerektirir.
Çözüm:
map[string]interface{}'yi, giriş verilerinin yapısının bilinmediği yerlerde kullanın. Anahtarın varlığını dikkatlice kontrol edin, türü (type assertion) yalnızca exists-idiom'dan sonra döndürün. Bu tür haritaları iş mantığının "derinlerinde" tutmamaya, bunun yerine sistemi sınırlarında bir adaptör olarak kullanmaya çalışın.
Kod örneği:
obj := map[string]interface{}{ "int": 42, "str": "merhaba", "flag": true, } if v, ok := obj["int"]; ok { n, success := v.(int) if success { fmt.Println(n) } }
Anahtar özellikler:
Anahtar eksik olduğunda map[string]interface{} içinde bir değere hata olmadan erişebilir miyiz?
Hayır, bu "zero value" (nil) değeri verecektir, tür dönüştürmesi (casting) belirli bir tür için panik yaratır.
İç içe dilimlere veya diğer map'lere sahip map[string]interface{} serileştirilirken ne olur?
JSON serileştirmesi yapıyı düzgün işletecektir, ancak varsayılan olarak desteklenmeyen türler (channels, fonksiyonlar) varsa, marşalizasyon hatası oluşur.
map[string]interface{}' içindeki iki değeri == ile karşılaştırabilir miyiz?
Hayır, interface{} yalnızca altında yatan değer karşılaştırılabilir olduğunda karşılaştırılabilir. Eğer map veya dilim bu yapıya girerse, karşılaştırma sırasında panik oluşur.
Uygulamada tüm mantık map[string]interface{} nesneleri üzerine kurulu, her denetçi/hizmet bunları derin çağrılarla aktarıyor.
Artılar:
Eksiler:
map[string]interface{} sadece dış arayüzlerle, giriş/çıkış verileriyle çalışmak için kullanılır, ardından normal yapılara dönüştürülür.
Artılar:
Eksiler: