前言:我對以下解決方案進行了優化和改進,並將其作爲庫發佈在此處:github.com/icza/dyno
。以下convert()
功能可用作dyno.ConvertMapI2MapS()
。
的問題是,如果你使用的最通用的interface{}
類型解組,由github.com/go-yaml/yaml
包使用的默認類型,以解組鍵值對將map[interface{}]interface{}
。
的第一個想法是使用map[string]interface{}
:
var body map[string]interface{}
但這種嘗試達不到,如果YAML配置的深度超過一個,因爲這body
地圖將包含更多的地圖,它的類型將再次map[interface{}]interface{}
。
問題是深度未知,並且可能有其他值不是地圖,所以使用map[string]map[string]interface{}
並不好。
一個可行的辦法是讓yaml
解組到interface{}
類型的值,並辦理結果遞歸,並且將每個遇到map[interface{}]interface{}
到map[string]interface{}
值。必須處理地圖和切片。
下面是該轉換器功能的例子:使用它
func convert(i interface{}) interface{} {
switch x := i.(type) {
case map[interface{}]interface{}:
m2 := map[string]interface{}{}
for k, v := range x {
m2[k.(string)] = convert(v)
}
return m2
case []interface{}:
for i, v := range x {
x[i] = convert(v)
}
}
return i
}
和:
func main() {
fmt.Printf("Input: %s\n", s)
var body interface{}
if err := yaml.Unmarshal([]byte(s), &body); err != nil {
panic(err)
}
body = convert(body)
if b, err := json.Marshal(body); err != nil {
panic(err)
} else {
fmt.Printf("Output: %s\n", b)
}
}
const s = `Services:
- Orders:
- ID: $save ID1
SupplierOrderCode: $SupplierOrderCode
- ID: $save ID2
SupplierOrderCode: 111111
`
輸出:
Input: Services:
- Orders:
- ID: $save ID1
SupplierOrderCode: $SupplierOrderCode
- ID: $save ID2
SupplierOrderCode: 111111
Output: {"Services":[{"Orders":[
{"ID":"$save ID1","SupplierOrderCode":"$SupplierOrderCode"},
{"ID":"$save ID2","SupplierOrderCode":111111}]}]}
有一點要注意:從YAML切換到JSON通過Go地圖,您將失去項目的順序,因爲Go地圖中的元素(鍵值對)沒有排序。這可能是也可能不是問題。
像這樣創建body var:'body:= make(map [string] interface {})' –