将 YAML 取消封送到具有 Go 中意外字段的结构



我在尝试使用github.com/go-yaml/yaml取消编组具有未导出字段的结构时遇到了问题。结构如下所示:

type Example struct {
ExportedField   string                     `yaml:"exported-field"`
OneMoreExported string                     `yaml:"one-more-exported"`
unexportedField map[string]*AnotherExample `yaml:"unexported-field"`
}
type AnotherExample struct {
Name string `yaml:"name"`
}

我想解组这样的 YAML 作为

exported-field: lorem ipsum
one-more-exported: dolor set
unexported-field:
something:
name: anything

我尝试的是自定义解编拆收器:

func (example *Example) UnmarshalYAML(unmarshal func(interface{}) error) error {
type Alias Example
tmp := struct {
UnexportedField map[string]*AnotherExample `yaml:"unexported-field"`
*Alias
}{
Alias: (*Alias)(example),
}
if err := unmarshal(&tmp); err != nil {
return err
}
if tmp.UnexportedField != nil {
example.unexportedField = tmp.UnexportedField
}
example.CopyJobNonNil(Example(*tmp.Alias)) // Copies all the non-nil fields from the passed Example instance
return nil
}

tmp调用unmarshal()后不包含任何字段,而是未导出字段 — 其他字段似乎被省略了。

Go Playground 上重现的问题(尽管由于依赖关系而不起作用):https://play.golang.org/p/XZg7tEPGXna

由于大多数 Go 解组包(包括encoding/*包)使用reflect包来获取结构字段,并且reflect无法访问未导出的结构字段,因此解编拆收器无法解析为未导出的字段。

也就是说,仍然有一种方法可以做到这一点。可以将 YAML 取消编组为具有公共字段的未导出类型,然后可以将该类型嵌入到导出的类型中。同一包中的 setter 和 setter 可以只使用嵌入的结构。

例如:

// Define the types...
type innerData struct {
ExportedField string
unexportedField string
}
type Data struct {
innerData
}

// and then...
d := Data{}
DoSomeUnmarshalling(yamlbytes, &d.innerData)

// and then you can use getters/setters/whatever on `Data`
func (d *Data) GetUnexported() string {
return d.innerData.unexportedField;
}

(警告:完全未经测试)

有关参考,请参阅 JSON 和处理未导出的字段。

相关内容

  • 没有找到相关文章

最新更新