英文:
Unmarshal YAML into unknown struct
问题
抱歉,标题可能有些混乱,我在表达这个问题时遇到了困难。假设我有一个像这样的YAML配置文件:
animals:
-
type: whale
options:
color: blue
name: Mr. Whale
features:
-
type: musician
options:
instruments:
- Guitar
- Violin
这只是一个很牵强的例子,但与我实际工作的情况非常类似。
现在我有一些结构体来将这个配置解组为:
type Config struct {
AnimalConfigs []*AnimalConfig `yaml:"animals"`
}
type AnimalConfig struct{
Type string
Options map[string]string // ????
Features []*FeatureConfig
}
type FeatureConfig struct{
Type string
Options ????
}
问题在于动物类型(如鲸鱼等)和特征(如音乐家等)不能提前确定,它们可以作为单独的模块添加,并且每个模块都可以有自己的配置。假设有人在使用这个库时想要添加自己的动物。我不知道这个动物是什么,它的选项是什么,以及它的特征是什么。我也不知道特征的结构。我只知道它将有一个type
属性和一个options
属性。我希望开发人员能够添加自定义的动物和特征,而我的库只需执行类似于YourAnimal.Create(yourConfig)
的操作。
我正在使用go-yaml库。正如你在AnimalConfig结构体中看到的,我最初的想法是将options
和features
设置为map[string]string
,然后让自定义模块将该字符串解组为它们自己的结构体。但是,对于musician
特征来说,这种方法行不通,因为instruments
是一个列表,而不是一个字符串。谢谢!
英文:
Sorry for the confusing title, I'm having trouble wording this question. So lets say I have a YAML config file like this
animals:
-
type: whale
options:
color: blue
name: Mr. Whale
features:
-
type: musician
options:
instruments:
- Guitar
- Violin
Very contrived example, but it's directly analogous to what I'm really working with.
So now I have some structs to marshal this config into
type Config struct {
AnimalConfigs []*AnimalConfig `yaml:"animals"`
}
type AnimalConfig struct{
Type string
Options map[string]string // ????
Features []*FeatureConfig
}
type FeatureConfig struct{
Type string
Options ????
}
So the problem here is that the animal types (whale, etc..), and features (musician, etc...) are not determined ahead of time, they can be added on as separate modules and can each have their own configurations. So say someone is using this library and wants to add their own animal. I do not know what this animal is, what it's options will be, and what it's features will be. I also don't know the structure of the feature's. All I know is that it will have a type
property, and an options
property. I would like the developer to be able to add custom animals and features, and my library can just do something like YourAnimal.Create(yourConfig)
.
I'm using the go-yaml library. As you can see in the AnimalConfig struct, my initial idea was to have the options
and features
just be map[string]string
, and then let the custom module unmarshal that string into their own struct, but that wouldn't work for example with the musician
feature because instruments
is a list, not a string. Thanks!
答案1
得分: 3
我认为你的问题大致是如何在不知道产生的结构的情况下解析YAML,是吗?如果是这样,我所做的是使用ghodss/yaml将YAML转换为JSON,然后使用标准的encoding/json
进行解析。这样可以得到一个包含YAML文档中所有内容的struct
,但你需要通过"类型切换"来处理它,并且键名可能事先不知道。
这里有一个示例:https://play.golang.org/p/8mcuot-lw0y
英文:
I think in general what you are asking is how to unmarshal YAML when you don't know the structure which will be produced, yes? If so, what I've done is use ghodss/yaml to convert YAML to JSON, then use the standard encoding/json
to unmarshal. This gets you a struct
with everything in the YAML doc, but you have to "type switch" your way through it, and key names, of course, may not be known a prioir.
Here's an example: https://play.golang.org/p/8mcuot-lw0y
答案2
得分: -1
你可以将配置文件的类型设置为map[string]interface{}
,然后让使用你的库的开发者将interface{}
解码为所需的结构体。
示例:https://play.golang.org/p/RVqKP09KR8
英文:
You could make your config of type map[string]interface{}
and let the developer using your library decode interface{}
into required struct.
Example: https://play.golang.org/p/RVqKP09KR8
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论