Я бы порекомендовал что-то совсем другое. Я обычно по возможности избегаю размышлений. Вы можете выполнить sh то, что вы пытаетесь сделать, просто предоставив структуры для каждого типа конфигурации, которую вы ожидаете, а затем выполните начальную «предварительную демаршализацию», чтобы определить, какой тип конфигурации вы действительно должны использовать по имени (что в данном case - это ключ вашего объекта JSON):
package main
import (
"encoding/json"
"fmt"
"os"
)
//Amqp1 config struct
type Amqp1 struct {
Config struct {
Test string `json:"test"`
Float float64 `json:"float"`
Connections []Connection `json:"connections"`
} `json:"Amqp1"`
}
//Connection struct
type Connection struct {
Type string `json:"type"`
URL string `json:"url"`
}
//JSONConfigContent json
const JSONConfigContent = `{
"Amqp1": {
"test": "woobalooba",
"float": 5.5,
"connections": [
{"type": "test1", "url": "booyaka"},
{"type": "test2", "url": "foobar"}
]
}
}`
func main() {
configMap := make(map[string]interface{})
if err := json.Unmarshal([]byte(JSONConfigContent), &configMap); err != nil {
fmt.Printf("unable to parse data from provided configuration file: %s\n", err)
os.Exit(1)
}
//get config name
var configName string
for cfg := range configMap {
configName = cfg
break
}
//unmarshal appropriately
switch configName {
case "Amqp1":
var amqp1 Amqp1
if err := json.Unmarshal([]byte(JSONConfigContent), &amqp1); err != nil {
fmt.Printf("unable to parse data from provided configuration file: %s\n", err)
os.Exit(1)
}
fmt.Printf("%s >>\n", configName)
fmt.Printf("Test: %s\n", amqp1.Config.Test)
fmt.Printf("Float: %v\n", amqp1.Config.Float)
fmt.Printf("Connections: %#v\n", amqp1.Config.Connections)
default:
fmt.Printf("unknown config encountered: %s\n", configName)
os.Exit(1)
}
}
Первоначальный «предварительный демаршаллинг» происходит во второй строке main () на простой карте, где ключом является строка, а value is interface {}, потому что вам все равно. Вы просто делаете это, чтобы получить реальный тип конфигурации, которая является ключом первого вложенного объекта.
Вы также можете запустить это на игровой площадке .