go - 如何合并两个相同结构类型的 Go 值?
问题描述
我想创建一个名为的函数,该函数merge()
接受同一个结构的两个值,但可以是任何结构,并返回两个结构的合并值。
我希望第一个值优先。例如,如果有两个结构a
和b
,在调用之后merge(a,b)
,如果有两个a
和b
包含的字段,我希望它具有a
该给定字段的值。
实现这一点的最佳方法是什么? https://play.golang.org/p/7s9PWx26gfz
type cat struct {
name string
color string
age int
}
type book struct {
title string
author string
}
func main() {
c1 := cat{
name: "Oscar",
color: "",
age: 3,
}
c2 := cat{
name: "",
color: "orange",
age: 2,
}
c3 := merge(c1, c2)
// want: c3 = cat{
// name: "Oscar",
// color: "orange",
// age: 3,
// }
// another case...
b1 := book{
title: "Lord of the Rings",
author: "John Smith",
}
b2 := book{
title: "Harry Potter",
author: "",
}
b3 := merge(b1, b2)
// want: b3 = book{
// title: "Lord of the Rings",
// author: "John Smith",
// }
}
这是我到目前为止所拥有的:
// merges two structs, where a's values take precendence over b's values (a's values will be kept over b's if each field has a value)
func merge(a, b interface{}) (*interface{}, error) {
var result interface{}
aFields := reflect.Fields(a)
bFields := reflect.Fields(b)
if !reflect.DeepEqual(aFields, bFields) {
return &result, errors.New("cannot merge structs of different struct types")
}
aValOf := reflect.ValueOf(a)
bValOf := reflect.ValueOf(b)
resultValOf := reflect.ValueOf(result)
aValues := make([]interface{}, aValOf.NumField())
resultValues := make([]interface{}, resultValOf.NumField())
for i := 0; i < aValOf.NumField(); i++ {
if reflect.ValueOf(aValues[i]).IsNil() {
resultValues[i] = bValOf.Field(i).Interface()
break
}
resultValues[i] = aValOf.Field(i).Interface()
}
return &result, nil
}
解决方案
检查这个包https://github.com/imdario/mergo
示例代码:
package main
import (
"fmt"
"github.com/imdario/mergo"
)
type Foo struct {
A string
B int64
}
func main() {
src := Foo{
A: "one",
B: 2,
}
dest := Foo{
A: "two",
}
mergo.Merge(&dest, src)
fmt.Println(dest)
// Will print
// {two 2}
}
在操场上看到它:https: //play.golang.org/p/9KWTK5mSZ6Q
推荐阅读
- magento2 - 在管理网格的自定义选项卡中显示产品名称
- sql - 在 MariaDB 中将一列与另一列合并的最佳解决方案是什么?
- php - 使用 php (curl) 将 Json 和音频文件发布到 laravel API
- sql - 我可以在 .NET Core 干净架构中使用 SQL 查询而不是实体框架吗?
- java - 使用工厂模式时如何保护具体子类的实例化?
- android - 检测Webview android中的URL更改
- java - 非拉丁字符显示为“?”
- python - Model gives same output, accuracy, loss for all inputs (keras)
- go - 如何使用 Go 在嵌套 JSON 中进行多步搜索
- angular - Angular material MatDialog.open(Component) automatically selects first link of Component