我有一个递归函数,它创建表示文件路径的对象(键是路径,值是关于文件的信息)。它是递归的,因为它只用于处理文件,所以如果遇到目录,该函数将在目录上递归调用。
话虽如此,我想在两个Map上做一个集合并集的等价物(即用来自递归调用的值更新的“main”Map)。除了在一个Map上迭代并将其中的每个键和值赋给另一个Map中的相同内容之外,有没有一种惯用的方法来做这件事?
也就是说:假设a,b
的类型为map [string] *SomeObject
,并且a
和b
最终会被填充,那么是否有办法用b
中的所有值更新a
?
6条答案
按热度按时间nsc4cvqm1#
没有内置的方式,也没有标准包中的任何方法来进行这样的合并。
惯用的方法是简单地迭代:
qxsslcnc2#
从Go语言1.18开始,你可以简单地使用
golang.org/x/exp/maps
包中的Copy
函数:(Playground)
输出:
这种方法的一个警告是你的Map的键类型必须是 concrete,也就是说不是接口类型,例如,编译器不允许你把
map[io.Reader]int
类型的值传递给Copy
函数:(Playground)
编译器输出:
proposal: spec: permit values to have type "comparable"中有关此限制的更多信息。
laximzn53#
从go 1.18开始,由于泛型特性的发布,现在有了union map的泛型函数!
你可以使用像https://github.com/samber/lo这样的包来实现这一点。注意键可以是任何“可比较的”类型,而值可以是任何类型。
示例:
结果是:
wsxa1bj14#
如果你有两个嵌套的Map
left
和right
,那么这个函数将递归地把right
中的项添加到left
中。如果这个键已经在left
中,那么我们将递归到这个结构的更深处,并且只尝试把 * 键添加a到left
中(例如,从不替换它们)。注意:我不处理值本身不是
map[string]interface{}
的情况,所以如果你有left["x"] = 1
和right["x"] = 2
,那么上面的代码在尝试leftVal.(m)
时会死机。64jmpszr5#
Go语言受map类型的限制。我怀疑由于map可以有无限多的类型声明,所以Go语言没有内置函数。所以你必须根据你使用的map类型来构建你自己的Merge函数:
py49o6xq6#
还有一个选择
github.com/samber/lo
,或者golang.org/x/exp
的实验性质感到不舒服(阅读警告),或append()
的API,而不是来自golang.org/x/exp
的exp.Copy()
(append接受任意数量的列表,而Copy()
只接受2个)。但是它需要Go语言1.18+,因为它使用了Go语言的泛型。
将以下内容保存到您的某个模块/包中:
然后,您可以非常类似于
append()
来使用它: