自定义 UnmarshalYAML,如何在自定义类型上实现 Unmarshaler 接口
Custom UnmarshalYAML, how to implement Unmarshaler interface on custom type
我解析了一个 .yaml 文件并需要以自定义方式解组其属性之一。我正在使用 "gopkg.in/yaml.v2"
包。
有问题的 属性 在我的 .yaml 文件中是这样存储的:
endPointNumberSequences:
AD1: [ 0, 10, 14, 1, 11, 2, 100, 101, 12 ]
所以它基本上是一种map[string][]uint16
类型。
但我需要 map[string]EpnSeq
其中 EpnSeq
定义为:
type EpnSeq map[uint16]uint16
我的结构:
type CitConfig struct {
// lots of other properties
// ...
EndPointNumberSequences map[string]EpnSeq `yaml:"endPointNumberSequences"`
}
我试过这样实现 Unmarshaler 接口:
// Implements the Unmarshaler interface of the yaml pkg.
func (e EpnSeq) UnmarshalYAML(unmarshal func(interface{}) error) error {
yamlEpnSequence := make([]uint16, 0)
err := unmarshal(&yamlEpnSequence)
if err != nil {
return err
}
for priority, epn := range yamlEpnSequence {
e[epn] = uint16(priority) // crashes with nil pointer
}
return nil
}
我的问题是 UnmarshalYAML
函数内部没有定义 EpnSeq
类型,导致运行时出现 nil 指针异常。
如何在此处正确实现 Unmarshaler 接口?
由于@Volker 没有post他的评论作为回答,为了完整起见,我会做。
所以我已经在正确的道路上,但在初始化它时只是未能取消引用我的结构的指针接收器:
// Implements the Unmarshaler interface of the yaml pkg.
func (e *EpnSeq) UnmarshalYAML(unmarshal func(interface{}) error) error {
yamlEpnSequence := make([]uint16, 0)
err := unmarshal(&yamlEpnSequence)
if err != nil {
return err
}
// make sure to dereference before assignment,
// otherwise only the local variable will be overwritten
// and not the value the pointer actually points to
*e = make(EpnSeq, len(yamlEpnSequence))
for priority, epn := range yamlEpnSequence {
e[epn] = uint16(priority) // no crash anymore
}
return nil
}
我解析了一个 .yaml 文件并需要以自定义方式解组其属性之一。我正在使用 "gopkg.in/yaml.v2"
包。
有问题的 属性 在我的 .yaml 文件中是这样存储的:
endPointNumberSequences:
AD1: [ 0, 10, 14, 1, 11, 2, 100, 101, 12 ]
所以它基本上是一种map[string][]uint16
类型。
但我需要 map[string]EpnSeq
其中 EpnSeq
定义为:
type EpnSeq map[uint16]uint16
我的结构:
type CitConfig struct {
// lots of other properties
// ...
EndPointNumberSequences map[string]EpnSeq `yaml:"endPointNumberSequences"`
}
我试过这样实现 Unmarshaler 接口:
// Implements the Unmarshaler interface of the yaml pkg.
func (e EpnSeq) UnmarshalYAML(unmarshal func(interface{}) error) error {
yamlEpnSequence := make([]uint16, 0)
err := unmarshal(&yamlEpnSequence)
if err != nil {
return err
}
for priority, epn := range yamlEpnSequence {
e[epn] = uint16(priority) // crashes with nil pointer
}
return nil
}
我的问题是 UnmarshalYAML
函数内部没有定义 EpnSeq
类型,导致运行时出现 nil 指针异常。
如何在此处正确实现 Unmarshaler 接口?
由于@Volker 没有post他的评论作为回答,为了完整起见,我会做。
所以我已经在正确的道路上,但在初始化它时只是未能取消引用我的结构的指针接收器:
// Implements the Unmarshaler interface of the yaml pkg.
func (e *EpnSeq) UnmarshalYAML(unmarshal func(interface{}) error) error {
yamlEpnSequence := make([]uint16, 0)
err := unmarshal(&yamlEpnSequence)
if err != nil {
return err
}
// make sure to dereference before assignment,
// otherwise only the local variable will be overwritten
// and not the value the pointer actually points to
*e = make(EpnSeq, len(yamlEpnSequence))
for priority, epn := range yamlEpnSequence {
e[epn] = uint16(priority) // no crash anymore
}
return nil
}