GoLang yaml unmarshal – updating structs

huangapple go评论76阅读模式
英文:

GoLang yaml unmarshal - updating structs

问题

我使用https://github.com/go-yaml/yaml库来解析yaml设置文件。
设置结构体需要稍作修改。

当前的结构体是:

type Settings struct{
   Hosts []string
}

新的结构体应该是:

type Host struct {
   URL  string
   Name string
}
type Settings struct{
   Hosts []Host
}

当前的yaml:

hosts:
-http://server1.com
-http://server2.com

新的yaml将是:

hosts:
- url:http://server1.com
  name:s1
- url:http://server2.com
  name:s2

我不想强制用户在实施更改后去更新yaml文件。我该如何解析这两个文件(新旧文件)?例如,如果接收到旧文件,我希望name字段为空。如果接收到新文件,我将使用提供的内容。

谢谢!

英文:

I use https://github.com/go-yaml/yaml library to parse yaml settings file.
The settings struct needs to change slightly.

The current struct is

type Settings struct{
   Hosts []string
}

The new struct should be

type Host struct {
   URL  string
   Name string
}
type Settings struct{
   Hosts []Host
}

Current yaml:

hosts:
-http://server1.com
-http://server2.com

The new yaml will be

hosts:
- url:http://server1.com
  name:s1
- url:http://server2.com
  name:s2

I don't want to force users to go and update the yaml file after the change is implemented. How can I parse both files (new and old)? For example, if the old file is received, I want name field to be empty. If the new file is received then I will take whatever is provided.

Thanks!

答案1

得分: 2

"正确的方法"是为Settings的新结构发布v2版本的软件包。v2的用户可以使用新的结构,而现有用户可以继续使用旧的结构和软件包的v1版本。

如果这不可行,另一种方法是将Settings声明为一个空接口的数组。

type Settings struct{
   Hosts []interface{}
}

使用这种方式,yaml将能够正确解析,并且你将在Hosts字段中得到以下数据:

  1. 对于旧的yaml,是一个string数组
  2. 对于新的yaml,是一个map[string]interface{}数组

需要使用类型断言将其解析为新的结构或旧的结构。

注意Hosts的类型将始终是[]interface{},需要对元素的类型进行断言以填充字段。

英文:

Correct way would be to release v2 of your package for new structure of Settings. Users of v2 can use new structure and existing users can keep using old structure with v1 of your package.

If this is not possible then another way is to declare Settings as array of empty interface.

type Settings struct{
   Hosts []interface{}
}

yaml will parse ok with this, and you will get data in Hosts fields as

  1. array of string for old yaml
  2. array of map[string]interface{} for new yaml

type assertion will be needed to parse that into new struct or old struct.

Note the type of Hosts will always be []interface{}, it is the elements whose type will need to be asserted to populate the fields.

huangapple
  • 本文由 发表于 2022年8月24日 20:59:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/73473656.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定