ANi*_*sus 85
没有内置方式,也没有标准包中的任何方法来进行这样的合并.
简单的方法是简单地迭代:
for k, v := range b {
a[k] = v
}
Run Code Online (Sandbox Code Playgroud)
jub*_*0bs 55
从Go 1.21开始,您可以简单地使用新maps.Copy函数:
package main
import (
"fmt"
"maps"
)
func main() {
src := map[string]int{
"one": 1,
"two": 2,
}
dst := map[string]int{
"two": 42,
"three": 3,
}
maps.Copy(dst, src)
fmt.Println("src:", src)
fmt.Println("dst:", dst)
}
Run Code Online (Sandbox Code Playgroud)
(游乐场)
输出:
src: map[one:1 two:2]
dst: map[one:1 three:3 two:2]
Run Code Online (Sandbox Code Playgroud)
从 Go 1.18 开始,您可以简单地使用包中的Copy函数golang.org/x/exp/maps:
package main
import (
"fmt"
"golang.org/x/exp/maps"
)
func main() {
src := map[string]int{
"one": 1,
"two": 2,
}
dst := map[string]int{
"two": 42,
"three": 3,
}
maps.Copy(dst, src)
fmt.Println("src:", src)
fmt.Println("dst:", dst)
}
Run Code Online (Sandbox Code Playgroud)
(游乐场)
输出:
src: map[one:1 two:2]
dst: map[one:1 three:3 two:2]
Run Code Online (Sandbox Code Playgroud)
这种方法的一个警告是,在 Go 版本 1.18.x 到 1.19.x 中,映射的键类型必须是具体的,即不是接口类型。例如,编译器不允许您将类型值传递map[io.Reader]int给Copy函数:
package main
import (
"fmt"
"io"
"golang.org/x/exp/maps"
)
func main() {
var src, dst map[io.Reader]int
maps.Copy(dst, src)
fmt.Println("src:", src)
fmt.Println("dst:", dst)
}
Run Code Online (Sandbox Code Playgroud)
编译器输出:
go: finding module for package golang.org/x/exp/maps
go: downloading golang.org/x/exp v0.0.0-20220328175248-053ad81199eb
./prog.go:12:11: io.Reader does not implement comparable
Go build failed.
Run Code Online (Sandbox Code Playgroud)
这个限制在 Go 1.20 (playground )中被取消。
Ami*_*tch 11
从 go 1.18 开始,由于泛型功能的发布,现在有了联合映射的泛型函数!
您可以使用https://github.com/samber/lo之类的包来执行此操作。请注意,键可以是任何“可比较”类型,而值可以是任何类型。
例子:
package main
import (
"fmt"
"github.com/samber/lo"
)
func main() {
map1 := map[string]interface{}{"k1": "v1", "k2": 2}
map2 := map[string]interface{}{"k2": "v2new", "k3": true}
map1 = lo.Assign(map1, map2)
fmt.Printf("%v", map1)
}
Run Code Online (Sandbox Code Playgroud)
结果是:
map[k1:v1 k2:v2new k3:true]
Run Code Online (Sandbox Code Playgroud)
如果您有几个嵌套的映射,left并且right,则此函数将递归地将项添加right到 中left。如果密钥已经存在,left那么我们会更深入地递归到结构中并尝试只向其中添加密钥left(例如,永远不要替换它们)。
type m = map[string]interface{}
// Given two maps, recursively merge right into left, NEVER replacing any key that already exists in left
func mergeKeys(left, right m) m {
for key, rightVal := range right {
if leftVal, present := left[key]; present {
//then we don't want to replace it - recurse
left[key] = mergeKeys(leftVal.(m), rightVal.(m))
} else {
// key not in left so we can just shove it in
left[key] = rightVal
}
}
return left
}
Run Code Online (Sandbox Code Playgroud)
注意:我不处理值本身不是 a 的情况map[string]interface{}。所以,如果你有left["x"] = 1和right["x"] = 2,然后尝试在上面的代码就会死机leftVal.(m)。