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.Unmarshal和#x2B;地图-如何覆盖_Go_Yaml - Fatal编程技术网

Go+;yaml.Unmarshal和#x2B;地图-如何覆盖

Go+;yaml.Unmarshal和#x2B;地图-如何覆盖,go,yaml,Go,Yaml,将Go中的两个结构与贴图合并的最简单方法是什么,这样现有键也会合并,而不是像默认情况下通过解组所做的那样被覆盖 具有更好解释的示例代码: 主程序包 进口( “fmt” “gopkg.in/yaml.v2” ) 类型应用程序结构{ 脚本字符串`yaml:“脚本”` 残疾儿童:“残疾”` 选项映射[string]string`yaml:“选项,省略为空”` } 类型配置结构{ 主机字符串`yaml:“主机”` 端口字符串`yaml:“端口”` 应用程序映射[string]应用程序`yaml:“应用

将Go中的两个结构与贴图合并的最简单方法是什么,这样现有键也会合并,而不是像默认情况下通过解组所做的那样被覆盖

具有更好解释的示例代码:

主程序包
进口(
“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建议。我不想说优雅,但我发现将地图转换为结构非常方便。谢谢你的建议。我决定实施合并解决方案,结果代码如下: