英文:
Working with interfaces using Viper language
问题
我正在使用Viper和Cobra构建一个小应用程序。目前,我有一个像这样的yaml文件:
hosts:
- name: host1
port: 90
key: my_key
- name: host2
port: 90
key: prompt
我使用Viper读取了配置文件。
当我运行viper.Get("hosts")
时,它返回一个接口(或接口切片?)。这是我得到的数据结构:
([]interface {}) (len=2 cap=2) {
(map[interface {}]interface {}) (len=3) {
(string) (len=4) "name": (string) (len=20) "host1",
(string) (len=4) "port": (int) 90,
(string) (len=3) "key": (string) (len=6) "my_key"
},
(map[interface {}]interface {}) (len=3) {
(string) (len=3) "key": (string) (len=6) "prompt",
(string) (len=4) "name": (string) (len=20) "host2",
(string) (len=4) "port": (int) 90
}
}
我想做的是遍历数组的每个元素,并使用name、port和key的值执行操作。
我对Golang中的接口完全不熟悉,所以这并不清楚,而且关于这方面的文献非常令人困惑
感谢任何帮助。
英文:
I am building a little app using Viper and Cobra. At the moment, I have a yaml file like this:
hosts:
- name: host1
port: 90
key: my_key
- name: host2
port: 90
key: prompt
And I've read in the config file using Viper.
When I run viper.Get("hosts")
it returns an interface (or a slice of interfaces?). This is the data structure I end up with:
([]interface {}) (len=2 cap=2) {
(map[interface {}]interface {}) (len=3) {
(string) (len=4) "name": (string) (len=20) "host1",
(string) (len=4) "port": (int) 90,
(string) (len=3) "key": (string) (len=6) "my_key"
},
(map[interface {}]interface {}) (len=3) {
(string) (len=3) "key": (string) (len=6) "prompt",
(string) (len=4) "name": (string) (len=20) "host2",
(string) (len=4) "port": (int) 90
}
}
What I'd like to do here is loop over each of the array elements and perform an operation using the values of name, port and key.
I'm completely new to interfaces in Golang, so this isn't very clear, and the literature on this is extremely confusing
Any help is appreciated.
答案1
得分: 10
通过定义配置文件类型并使用viper.Unmarshal
,您可以将接口转换为所需的特定类型。这里是一个示例:
main.go
package main
import (
"fmt"
"github.com/spf13/viper"
)
type Host struct {
Name string
Port int
Key string
}
type Config struct {
Hosts []Host
}
func main() {
viper.AddConfigPath("./")
viper.SetConfigName("test")
viper.ReadInConfig()
var config Config
err := viper.Unmarshal(&config)
if err != nil {
panic("无法解析配置")
}
for _, h := range config.Hosts {
fmt.Printf("Name: %s, Port: %d, Key: %s\n", h.Name, h.Port, h.Key)
}
}
test.yml
hosts:
- name: host1
port: 90
key: my_key
- name: host2
port: 90
key: prompt
运行:
$ go run main.go
Name: host1, Port: 90, Key: my_key
Name: host2, Port: 90, Key: prompt
如果您只想解码某些键,而不是整个配置文件,请使用viper.UnmarshalKey
。
main.go
package main
import (
"fmt"
"github.com/spf13/viper"
)
type Host struct {
Name string
Port int
Key string
}
func main() {
viper.AddConfigPath("./")
viper.SetConfigName("test")
viper.ReadInConfig()
var hosts []Host
err := viper.UnmarshalKey("hosts", &hosts)
if err != nil {
panic("无法解析主机")
}
for _, h := range hosts {
fmt.Printf("Name: %s, Port: %d, Key: %s\n", h.Name, h.Port, h.Key)
}
}
运行:
$ go run main.go
Name: host1, Port: 90, Key: my_key
Name: host2, Port: 90, Key: prompt
英文:
By defining the configuration file type and using viper.Unmarshal
you can cast the interface to the specific type you need. Here is an example:
main.go
package main
import (
"fmt"
"github.com/spf13/viper"
)
type Host struct {
Name string
Port int
Key string
}
type Config struct {
Hosts []Host
}
func main() {
viper.AddConfigPath("./")
viper.SetConfigName("test")
viper.ReadInConfig()
var config Config
err := viper.Unmarshal(&config)
if err != nil {
panic("Unable to unmarshal config")
}
for _, h := range config.Hosts {
fmt.Printf("Name: %s, Port: %d, Key: %s\n", h.Name, h.Port, h.Key)
}
}
test.yml
hosts:
- name: host1
port: 90
key: my_key
- name: host2
port: 90
key: prompt
Run:
$ go run main.go
Name: host1, Port: 90, Key: my_key
Name: host2, Port: 90, Key: prompt
If you want to decode only some keys, not the entire configuration file, use viper.UnmarshalKey
.
main.go
package main
import (
"fmt"
"github.com/spf13/viper"
)
type Host struct {
Name string
Port int
Key string
}
func main() {
viper.AddConfigPath("./")
viper.SetConfigName("test")
viper.ReadInConfig()
var hosts []Host
err := viper.UnmarshalKey("hosts", &hosts)
if err != nil {
panic("Unable to unmarshal hosts")
}
for _, h := range hosts {
fmt.Printf("Name: %s, Port: %d, Key: %s\n", h.Name, h.Port, h.Key)
}
}
Run:
$ go run main.go
Name: host1, Port: 90, Key: my_key
Name: host2, Port: 90, Key: prompt
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论