Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如何解析YAML文件并从父结构创建子对象(继承)_Go_Inheritance_Yaml - Fatal编程技术网

Go 如何解析YAML文件并从父结构创建子对象(继承)

Go 如何解析YAML文件并从父结构创建子对象(继承),go,inheritance,yaml,Go,Inheritance,Yaml,假设我有以下结构: type CarShop struct { Cars []*Car } type Car struct { ID string `yaml:“id“` } type BMW struct { Car A string `yaml:“a“` } type Mercedes struct { Car B string `yaml:“b“ } 我想分析以下字符串: - BMW: id: „BMW“ a: „a“ - Mercedes:

假设我有以下结构:

type CarShop struct {
  Cars []*Car
}

type Car struct {
  ID string `yaml:“id“`
}

type BMW struct {
  Car
  A string `yaml:“a“`
}

type Mercedes struct {
  Car
  B string `yaml:“b“
}
我想分析以下字符串:

- BMW:
    id: „BMW“
    a: „a“
- Mercedes:
    id: „Mercedes“
    b: „b“

要动态创建解析此字符串的BMW和Mercedes对象,我必须做什么?甚至可以使用Go和Go yaml吗?

您的类型是错误的,Go没有继承。您不能将
*梅赛德斯
*宝马
类型的值存储到
[]*汽车
类型的数组中;这两种类型都只包含一个作为mixin的
Car
值。要做您想做的事情,您必须将
Car
类型更改为一个界面

现在是YAML部分:您可以将YAML结构的一部分存储在类型为
YAML.Node
的对象中,并在以后对其进行反序列化。您可以通过实现
unmarshalyml
(从
yaml.unmarshaler
界面)来实现自定义解组器。因此,我们要做的是为
CarShop
实现一个自定义解组器,它将周围的结构反序列化为一个列表,其中包含从car type到
yaml.Node
(该类型的值)的映射,然后根据给定的car type,将每个节点反序列化为适当的类型。下面是它的外观:

主程序包
进口(
“错误”
“fmt”
“gopkg.in/yaml.v3”
)
类型CarShop结构{
汽车
}
类型车辆接口{
ID()字符串
}
BMW型结构{
IDVal字符串`yaml:“id”`
字符串'yaml:'A'`
}
func(bmw*bmw)ID()字符串{
返回bmw.IDVal
}
梅赛德斯结构型{
IDVal字符串`yaml:“id”`
B字符串'yaml:'B'`
}
func(merc*Mercedes)ID()字符串{
返回merc.IDVal
}
键入tmpCarShop[]map[string]yaml.Node
func(cs*CarShop)解组字符串(值*yaml.Node)错误{
var tmp tmpCarShop
如果错误:=value.Decode(&tmp);错误!=nil{
返回错误
}
汽车:=制造([]汽车,0,透镜(tmp))
对于i:=范围tmp{
对于种类,原始:=范围tmp[i]{
开关类{
案例“梅赛德斯”:
m:=&Mercedes{}
如果错误:=raw.Decode(m);错误!=nil{
返回错误
}
车=附加(车,m)
案例“宝马”:
b:=&BMW{}
如果错误:=raw.Decode(b);错误!=nil{
返回错误
}
汽车=附加(汽车,b)
违约:
返回错误。新建(“未知车型:+种类”)
}
}
}
cs.汽车=汽车
归零
}
func main(){
输入:=[]字节(`
-宝马:
id:“宝马”
a:“a”
-梅赛德斯:
id:“梅赛德斯”
b:“b”
`)
汽车店
如果错误:=yaml.Unmarshal(输入和存储);错误!=nil{
恐慌(错误)
}
对于i:=靶场商店。汽车{
fmt.Printf(“ID:%s\n”,shop.Cars[i].ID())
开关c:=车间车辆[i](类型){
案例*梅赛德斯:
fmt.Printf(“类型:Mercedes\nA:%s\n”,c.B)
案例*宝马:
fmt.Printf(“类型:BMW\nB:%s\n”,c.A)
}
格式打印项次(“--”)
}
}

您的类型错误,Go没有继承。您不能将
*梅赛德斯
*宝马
类型的值存储到
[]*汽车
类型的数组中;这两种类型都只包含一个作为mixin的
Car
值。要做您想做的事情,您必须将
Car
类型更改为一个界面

现在是YAML部分:您可以将YAML结构的一部分存储在类型为
YAML.Node
的对象中,并在以后对其进行反序列化。您可以通过实现
unmarshalyml
(从
yaml.unmarshaler
界面)来实现自定义解组器。因此,我们要做的是为
CarShop
实现一个自定义解组器,它将周围的结构反序列化为一个列表,其中包含从car type到
yaml.Node
(该类型的值)的映射,然后根据给定的car type,将每个节点反序列化为适当的类型。下面是它的外观:

主程序包
进口(
“错误”
“fmt”
“gopkg.in/yaml.v3”
)
类型CarShop结构{
汽车
}
类型车辆接口{
ID()字符串
}
BMW型结构{
IDVal字符串`yaml:“id”`
字符串'yaml:'A'`
}
func(bmw*bmw)ID()字符串{
返回bmw.IDVal
}
梅赛德斯结构型{
IDVal字符串`yaml:“id”`
B字符串'yaml:'B'`
}
func(merc*Mercedes)ID()字符串{
返回merc.IDVal
}
键入tmpCarShop[]map[string]yaml.Node
func(cs*CarShop)解组字符串(值*yaml.Node)错误{
var tmp tmpCarShop
如果错误:=value.Decode(&tmp);错误!=nil{
返回错误
}
汽车:=制造([]汽车,0,透镜(tmp))
对于i:=范围tmp{
对于种类,原始:=范围tmp[i]{
开关类{
案例“梅赛德斯”:
m:=&Mercedes{}
如果错误:=raw.Decode(m);错误!=nil{
返回错误
}
车=附加(车,m)
案例“宝马”:
b:=&BMW{}
如果错误:=raw.Decode(b);错误!=nil{
返回错误
}
汽车=附加(汽车,b)
违约:
返回错误。新建(“未知车型:+种类”)
}
}
}
cs.汽车=汽车
归零
}
func main(){
输入:=[]字节(`
-宝马:
id:“宝马”
a:“a”
-梅赛德斯:
id:“梅赛德斯”
b:“b”
`)
汽车店
如果错误:=yaml.Unmarshal(输入和存储);错误!=nil{
恐慌(错误)
}
对于i:=靶场商店。汽车{
fmt.Printf(“ID:%s\n”,shop.Cars[i].ID())
开关c:=车间车辆[i](类型){
案例*梅赛德斯:
fmt.Printf(“类型:Mercedes\nA:%s\n”,c.B)
案例*宝马:
fmt.Printf(“类型:BMW\nB:%s\n”,c.A)
}
格式打印项次(“--”)
}
}

您是否尝试过用Car实现解组器接口?谢谢您的建议!我认为