我正在读取一个 yaml 文件,并将其解码为一个 map[interface{}]interface{}
。目标是替换 yaml 中的某个值,并用替换的值更新读入的文件。我不确定如何解析 map 以获取我想要更改的特定 key (password
)。我相信你可以使用 reflect
,但我不是 100% 确定语法
我正在阅读的 YAML 文件 (config.yml
):
i_name: example
instances:
- name: test-instance
command: get
arguments:
hostname: localhost
port: 203
username: test
password: testing123
labels:
env: dev
到目前为止的代码:
func replaceConfigPassword() {
yamlFile, err := ioutil.ReadFile("config.yml")
fatalIfErr(err)
m := make(map[interface{}]interface{})
err = yaml.Unmarshal(yamlFile, &m)
fatalIfErr(err)
fmt.Println(m)
val := reflect.ValueOf(m["instances"]["arguments"]["password"])
fmt.Println("val=", val)
最佳答案
下面显示了如何逐步执行 yaml 以获取密码:
package main
import (
"fmt"
"gopkg.in/yaml.v2"
)
func main() {
in := []byte(`
i_name: example
instances:
- name: test-instance
command: get
arguments:
hostname: localhost
port: 203
username: test
password: testing123
labels:
env: dev
`)
m := make(map[string]interface{})
if err := yaml.Unmarshal(in, &m); err != nil {
panic(err)
}
fmt.Printf("%+v\n", m)
instances := m["instances"].([]interface{})
fmt.Printf("%+v\n", instances)
first := instances[0]
fmt.Printf("%+v\n", first)
arguments := first.(map[interface{}]interface{})["arguments"]
fmt.Printf("%+v\n", arguments)
password := arguments.(map[interface{}]interface{})["password"]
fmt.Printf("%+v\n", password)
}
$ go run main.go
map[i_name:example instances:[map[name:test-instance command:get arguments:map[password:testing123 hostname:localhost port:203 username:test] labels:map[env:dev]]]]
[map[name:test-instance command:get arguments:map[hostname:localhost port:203 username:test password:testing123] labels:map[env:dev]]]
map[name:test-instance command:get arguments:map[hostname:localhost port:203 username:test password:testing123] labels:map[env:dev]]
map[username:test password:testing123 hostname:localhost port:203]
testing123
如果您事先知道输入结构,另一种选择是对其进行显式建模:
type Config struct {
IName string `yaml:"i_name"`
Instances []struct{
Name string
Command string
Arguments map[string]interface{}
Labels map[string]string
}
}
var c Config
if err := yaml.Unmarshal(in, &c); err != nil {
panic(err)
}
fmt.Printf("%+v\n", c)
fmt.Printf("%+v\n", c.Instances[0].Arguments["password"])
$ go run main.go
{IName:example Instances:[{Name:test-instance Command:get Arguments:map[hostname:localhost port:203 username:test password:testing123] Labels:map[env:dev]}]}
testing123
关于go - 如何从 map 界面解析特定键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55635827/