英文:
Go Interface/Container usage
问题
新手Go程序员在这里。我正在编写一个读取JSON配置文件的包。当然,它使用了内置的JSON解码器。但是我希望它能够包含其他的JSON文件,通过查找一个带有键为'Includes'的文件名数组。我已经将其作为一个函数工作,并传入一个包含了一个标记为'Includes'的字符串切片的JSON数据的结构体,但我不知道如何将其指定为一个包。
以下是该函数的代码:
func ReadConfig(filename string, configuration *Configuration) error {
log.Println("reading file", filename)
file, err := os.Open(filename)
if err != nil {
log.Println("Can't read", filename)
return err
}
decoder := json.NewDecoder(file)
if err := decoder.Decode(&configuration); err != nil {
log.Println(err)
return err
}
includes := make([]string, len(configuration.Includes))
copy(includes, configuration.Includes)
configuration.Includes = configuration.Includes[0:0]
for _, inc := range includes {
log.Println(inc)
if err := ReadConfig(inc, configuration); err != nil {
return err
}
}
return nil
}
这段代码可以与以下结构体一起使用:
type Configuration struct {
Includes []string
.... 其他定义
}
但是,在一个包中,我希望ReadConfig函数可以接受任何类型的Configuration结构体,只要其中一个成员是'Includes []string'。
我认为我需要将ReadConfig函数的定义更改为:
func ReadConfig(filename string, configuration interface{})
但我不知道如何在其中访问Includes切片。
英文:
Newbie Go programmer here. I'm writing a package that reads a JSON configuration file. It uses the built-in JSON decoding, of course. But I want it to be able to include other JSON files as well, by looking for an array of filenames with the key of 'Includes'. I got it working as just a function and passing in a struct for the JSON data that includes a slice of strings labeled 'Includes', but I don't know how to specify this as a package.
Here's the function:
func ReadConfig(filename string, configuration *Configuration) error {
log.Println("reading file", filename)
file, err := os.Open(filename)
if err != nil {
log.Println("Can't read", filename)
return err
}
decoder := json.NewDecoder(file)
if err := decoder.Decode(&configuration); err != nil {
log.Println(err)
return err
}
includes := make([]string, len(configuration.Includes))
copy(includes, configuration.Includes)
config.Includes = configuration.Includes[0:0]
for _, inc := range includes {
log.Println(inc)
if err := ReadConfig(inc, configuration); err != nil {
return err
}
}
return nil
}
Which works with:
type Configuration struct {
Includes []string
.... other defs
}
But, in a package, I want ReadConfig to take any kind Configuration struct, as long as one of its members is 'Includes []string'.
I believe I need to change the ReadConfig def to:
func ReadConfig(filename string, configuration interface{})
But what I don't know is how to access the Includes slice within that.
答案1
得分: 3
只需为其创建一个接口
type Configurable interface {
Configuration() []string
}
然后为你的结构体提供一个 Configuration
方法而不是字段,并将函数的签名更改为 func ReadConfig(filename string, configuration Configurable)
。
不过,直接传递切片而不是结构体会更容易一些。
英文:
Just create an interface for it
type Configurable interface {
Configuration() []string
}
And then provide a Configuration
method instead of a field for your structs, and change the signature of your function to func ReadConfig(filename string, configuration Configurable)
.
It'd be much easier to just pass in the slice instead of the struct though.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论