切片作为地图中的关键

时间:2013-11-30 06:51:52

标签: go

是否可以将切片用作键?

有我的尝试:

h := map[[]string]string{
  []string{"a", "b"} : "ab",
}

编译器给我一个错误invalid map key type []string。所以要么它不可能,要么我声明错误(如果是这样,那将是一种正确的方法?)。

5 个答案:

答案 0 :(得分:31)

但是,使用数组作为映射键是possible

import "fmt"

func main() {
    m := make(map[[2]int]bool)
    m[[2]int{1, 2}] = false
    fmt.Printf("%v", m)
}

答案 1 :(得分:22)

不,切片不能用作映射键,因为没有定义相等。

答案 2 :(得分:9)

沃尔克已经说过这是不可能的,我会用规范中的例子给出一些更详细的信息。

Map spec告诉你:

  

必须为操作数完全定义比较运算符==和!=   关键类型;因此,键类型不能是函数,映射或   切片。

它已经告诉您切片不能成为密钥,但您也可以在comparison spec中检查它:

  

切片,贴图和函数值无法比较。

这意味着切片也不能成为密钥,数组也可以是密钥。例如,你可以写:

h := map[[2]string]string{
  [2]string{"a", "b"} : "ab",
}

答案 3 :(得分:1)

根据您的要求和数据的复杂程度,您可以使用字符串作为映射键,然后使用切片的哈希作为映射键。

好处是你可以将这种技术用于任何可以转换为或从一片字节转换的东西。

这是一种将字符串片段转换为字节片段的快捷方法:

[]byte(strings.Join([]string{},""))

以下是使用SHA1的示例:

type ByteSliceMap struct {
    buf *bytes.Buffer
    m   map[string][]byte
}

func (b *ByteSliceMap) key(buf []byte) string {
    h := sha1.New()
    h.Write(buf)
    sum := h.Sum(nil)
    return fmt.Sprintf("%x", sum)
}

func (t *ByteSliceMap) value(key []byte) (value []byte, ok bool) {
    value, ok = t.m[t.key(key)]
    return
}


func (t *ByteSliceMap) add(key, value []byte) {
    if t.m == nil {
        t.m = make(map[string][]byte)
    }
    t.m[t.key(key)] = value
}

Working version

答案 4 :(得分:0)

解决此问题的一种方法是从切片中创建一个具有明确定义的比较运算符的键:

func createKey(s []string) string { return fmt.Sprintf("%q", s) }

m := make(map[string]string)
s := []string{"a","b"}
m[createKey(s)] = "myValue"

以类似的方式,您必须创建用于创建类型与字符串不同的切片键的函数。