是否有一个与Python的ChainMap等效的golang软件包?

时间:2019-03-25 03:05:39

标签: go

Python的ChainMap使您可以将多个地图链接在一起,以便查找顺序搜索所有地图,直到找到匹配的键为止。这是关于它的众多文章之一:

https://dzone.com/articles/python-201-what-is-a-chainmap

以及官方文档:

https://docs.python.org/3/library/collections.html

有人知道Go编写的任何现有等效软件包吗?到目前为止,我一直找不到它,并希望避免重新发明轮子(如果确实存在)。

2 个答案:

答案 0 :(得分:0)

没有包,但是实现类似的东西很简单:

让我们用map[string]interface{}

package main

import (
        "reflect"
        "testing"
)

type ChainMap struct {
        Map  map[string]interface{}
        maps []map[string]interface{}
}

func NewChainMap(maps ...map[string]interface{}) ChainMap {
        if len(maps) == 0 {
                return ChainMap{
                        Map:  make(map[string]interface{}, 0),
                        maps: maps,
                }
        }
        r := make(map[string]interface{}, len(maps[0]))
        for i := len(maps) - 1; i >= 0; i-- {
                m := maps[i]
                for k, v := range m {
                        r[k] = v
                }
        }
        return ChainMap{
                Map:  r,
                maps: maps,
        }
}

func (c ChainMap) Parents() ChainMap {
        if len(c.maps) < 2 {
                return c
        }
        return NewChainMap(c.maps[1:]...)
}

一个小测试:

func TestChainMap(t *testing.T) {
        var m = NewChainMap(
                map[string]interface{}{
                        "foo": "bar",
                },
                map[string]interface{}{
                        "foo":   "baz",
                        "hello": "world",
                },
                map[string]interface{}{
                        "foo": "baw",
                },
        )
        if !reflect.DeepEqual(
                m.Map,
                map[string]interface{}{
                        "foo":   "bar",
                        "hello": "world",
                },
        ) {
                t.Fail()
        }

        if !reflect.DeepEqual(
                m.Parents().Map,
                map[string]interface{}{
                        "foo":   "baz",
                        "hello": "world",
                },
        ) {
                t.Fail()
        }
}

答案 1 :(得分:0)

现在偶然发现埋在bigkevmcd / go-configparser软件包中的实现:https://github.com/bigkevmcd/go-configparser/blob/master/chainmap/chainmap.go

这一点的好处是它使用原始地图进行存储,因此,如果其中之一稍后进行更新,那么这样做也是正确的。这使其工作起来更像原始的python版本。缺点是调用者需要调用Get()和Len()函数,而不是简单地将对象用作法线贴图。