3 回答
TA贡献1856条经验 获得超17个赞
reflect.New 返回一个表示指针的值。更改第 69 行:
fmt.Printf(">>> %v", &parsed)
结果:
>>> <struct { Amqp1 struct { Test string "json:\"test\""; Float float64 "json:\"float\""; Connections []main.Connection "json:\"connections\"" } } Value>
TA贡献1783条经验 获得超4个赞
我会推荐一些非常不同的东西。我通常会尽可能避免反思。您可以通过简单地为您期望的每种配置类型提供结构来完成您想要做的事情,然后进行初始“预解组”以确定您应该按名称实际使用的配置类型(在这种情况下是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() 的第二行,到一个普通的映射,其中键是字符串,值是 interface{},因为你不在乎。您这样做只是为了获取实际的配置类型,这是第一个嵌套对象的键。
TA贡献1859条经验 获得超6个赞
你想用来.Interface()返回实际的底层值,它应该是一个指向具体匿名结构的指针。
请注意,该reflect.New函数返回一个reflect.Value 表示指向指定类型的新零值的指针。Interface在这种情况下,该方法返回该指针,interface{}这就是您所需要的json.Unmarshal。
如果在解组之后,您需要结构的非指针,您可以再次反射并使用它reflect.ValueOf(parsed).Elem().Interface()来有效地取消引用指针。
parsed := reflect.New(reflect.StructOf(sections)).Interface()
if err := json.Unmarshal([]byte(JSONConfigContent), parsed); err != nil {
fmt.Printf("unable to parse data from provided configuration file: %s\n", err)
os.Exit(1)
}
https://play.golang.org/p/Bzu1hUyKjvM
- 3 回答
- 0 关注
- 88 浏览
添加回答
举报