【发布时间】:2017-01-04 08:14:45
【问题描述】:
如何在 Go 中解析 YAML 数据,而不事先知道其结构?我见过的所有示例都假设您想要解码您已经知道其键的封送映射。如果你不知道钥匙怎么办?如果它不是地图而是封送列表、标量或其他一些常见类型怎么办?
虽然我主要关注 YAML,但在这里,该技术似乎通常对 JSON 等有用。因为解析结构化数据(显然是标记结构)有一个通用模式。
【问题讨论】:
如何在 Go 中解析 YAML 数据,而不事先知道其结构?我见过的所有示例都假设您想要解码您已经知道其键的封送映射。如果你不知道钥匙怎么办?如果它不是地图而是封送列表、标量或其他一些常见类型怎么办?
虽然我主要关注 YAML,但在这里,该技术似乎通常对 JSON 等有用。因为解析结构化数据(显然是标记结构)有一个通用模式。
【问题讨论】:
对于 JSON,将数据解组为 interface{} 值。使用类型断言来确定值中的内容。
var v interface{}
err := json.Unmarshal(data, &v)
if err != nil {
// handle error
}
switch v := v.(type) {
case string:
fmt.Println("string:", v)
case float64:
fmt.Println("number:", v)
case []interface{}:
fmt.Println("array:", v)
case map[string]interface{}:
fmt.Println("object:", v)
case nil:
fmt.Println("nil")
}
【讨论】:
在 JSON 的情况下,标准库 json.Unmarshal 函数将根据需要解组任意 JSON,如果您将指针传递给未初始化的空接口。 (见this example.)
official docs 也说了这么多:
为了将 JSON 解组为接口值,Unmarshal 将其中一项存储在接口值中:
bool,用于 JSON 布尔值
float64,用于 JSON 数字
字符串,用于 JSON 字符串
[]接口{},用于 JSON 数组
map[string]interface{},用于 JSON 对象
JSON 为空
编辑:虽然没有记录,但yaml 包也是如此;我在我的工作站上进行了测试,传入一个指向未初始化的空接口的指针会导致正确的数组、映射和原语的初始化。
【讨论】: