英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论