Go+;yaml.Unmarshal和#x2B;地图-如何覆盖
将Go中的两个结构与贴图合并的最简单方法是什么,这样现有键也会合并,而不是像默认情况下通过解组所做的那样被覆盖 具有更好解释的示例代码:Go+;yaml.Unmarshal和#x2B;地图-如何覆盖,go,yaml,Go,Yaml,将Go中的两个结构与贴图合并的最简单方法是什么,这样现有键也会合并,而不是像默认情况下通过解组所做的那样被覆盖 具有更好解释的示例代码: 主程序包 进口( “fmt” “gopkg.in/yaml.v2” ) 类型应用程序结构{ 脚本字符串`yaml:“脚本”` 残疾儿童:“残疾”` 选项映射[string]string`yaml:“选项,省略为空”` } 类型配置结构{ 主机字符串`yaml:“主机”` 端口字符串`yaml:“端口”` 应用程序映射[string]应用程序`yaml:“应用
主程序包
进口(
“fmt”
“gopkg.in/yaml.v2”
)
类型应用程序结构{
脚本字符串`yaml:“脚本”`
残疾儿童:“残疾”`
选项映射[string]string`yaml:“选项,省略为空”`
}
类型配置结构{
主机字符串`yaml:“主机”`
端口字符串`yaml:“端口”`
应用程序映射[string]应用程序`yaml:“应用程序,省略为空”`
}
常量数据原始=
`主机:本地主机
端口:8080
应用:
附录1:
脚本:app1.sh
附录2:
脚本:app2.sh
附件3:
脚本:app3.sh
选项:
选项1:值1
选项2:价值2
`
常量数据覆盖=
`港口:9999
应用:
附录1:
脚本:NEW-app1.sh
附录2:
残疾人士:对
附件3:
选项:
选项2:新值2
选项3:新值3
`
预期常数数据=
`主机:本地主机
港口:9999
应用:
附录1:
脚本:NEW-app1.sh
附录2:
脚本:app2.sh
残疾人士:对
附件3:
脚本:app3.sh
选项:
选项1:值1
选项2:新值2
选项3:新值3
`
func main(){
变量配置
如果错误:=yaml.Unmarshal([]字节(dataOriginal),&config);错误!=nil{
恐慌(错误)
}
如果错误:=yaml.Unmarshal([]字节(数据覆盖),&config);错误!=nil{
恐慌(错误)
}
fmt.Printf(“实际值:%+v\n”,配置)
var配置预期配置
如果错误:=yaml.Unmarshal([]字节(dataExpected),&configExpected);错误!=nil{
恐慌(错误)
}
fmt.Printf(“预期:%+v\n”,预期配置)
}
产出:
Actual: {Host:localhost Port:9999 Applications:map[app1:{Script:NEW-app1.sh Disabled:false Options:map[]} app2:{Script: Disabled:true Options:map[]} app3:{Script: Disabled:false Options:map[option2:NEW-value2 option3:NEW-value3]}]}
Expected: {Host:localhost Port:9999 Applications:map[app1:{Script:NEW-app1.sh Disabled:false Options:map[]} app2:{Script:app2.sh Disabled:true Options:map[]} app3:{Script:app3.sh Disabled:false Options:map[option1:value1 option2:NEW-value2 option3:NEW-value3]}]}
我可以手动合并它们,这不难做到。但在这种情况下,需要随着配置结构的更改更新合并代码。对于给定的配置结构,还有其他不特定的方法吗?最优雅、最容易传递的问题是将yaml本身的默认值设置为:
const dataOverride =
`
.app1: &app1
script: app1.sh
.app2: &app2
script: app2.sh
.app3: &app3
script: app3.sh
options:
option1: value1
option2: value2
.default-settings: &default-settings
host: localhost
port: 8080
applications:
app1:
<<: *app1
app2:
<<: *app2
app3:
<<: *app3
<<: *default-settings
port: 9999
applications:
app1:
<<: *app1
script: NEW-app1.sh
app2:
<<: *app2
disabled: true
app3:
<<: *app3
options:
option2: NEW-value2
option3: NEW-value3
`
const dataOverride=
`
.app1:&app1
脚本:app1.sh
.app2:&app2
脚本:app2.sh
.app3:&app3
脚本:app3.sh
选项:
选项1:值1
选项2:价值2
.默认设置:&默认设置
主机:本地主机
端口:8080
应用:
附录1:
因为“优雅”是一个意见问题,所以很难回答这个问题。有一些工具可以促进类似这样的事情。我想到了。但它是否更“优雅”完全是主观的。我倾向于使用自定义代码,而不是使用反射的常规代码。让我们用一个不与配置结构耦合的想法来代替优雅。更改配置结构后保留相同的“合并”代码。我想明确支持mapstructure建议。我不想说优雅,但我发现将地图转换为结构非常方便。谢谢你的建议。我决定实施合并解决方案,结果代码如下: