Dictionary 使用包含切片字段的结构作为Go中的映射键的惯用方法是什么?

Dictionary 使用包含切片字段的结构作为Go中的映射键的惯用方法是什么?,dictionary,struct,go,key,slice,Dictionary,Struct,Go,Key,Slice,我有一个包含切片的结构,我想将它用作映射的键。我理解这是不允许的,因为当前没有为Go中的切片定义相等。我还知道,我不能重写结构的相等性来手动执行切片比较。我的问题是:完成我在这里要做的事情最惯用的方式是什么 这是一段示例代码,使结构更加清晰: package main import "fmt" type InternalStruct struct { item1, item2 bool } type ContainerStruct struct { internals []

我有一个包含切片的结构,我想将它用作映射的键。我理解这是不允许的,因为当前没有为Go中的切片定义相等。我还知道,我不能重写结构的相等性来手动执行切片比较。我的问题是:完成我在这里要做的事情最惯用的方式是什么

这是一段示例代码,使结构更加清晰:

package main

import "fmt"

type InternalStruct struct {
    item1, item2 bool
}

type ContainerStruct struct {
    internals []InternalStruct
}

func main() {
    container1 := ContainerStruct{}
    container1.internals = append(container1.internals, InternalStruct{item1: true})

    container2 := ContainerStruct{}
    container2.internals = append(container2.internals, InternalStruct{item1: true})

    m := make(map[ContainerStruct]int)
    m[container1] = 10

    fmt.Printf("container1 maps to: %d\n", m[container1])
    fmt.Printf("container1 maps to: %d\n", m[container2])
}

这段代码并没有按照预期编译,但我正在寻找一个等价的东西,可以输出10次。实现此结果的最佳方法是什么?

您不能将切片用作映射键,但如果您知道此类切片的大小,则可以使用数组。允许数组作为映射键

package main

import "fmt"

func main() {
    m := make(map[[2]int]int)

    m[[2]int{1, 2}] = 3
    m[[2]int{3, 4}] = 1

    fmt.Println(m)
}

即使您用相同的ptr、cap和len定义了slice equality,您想要的仍然不起作用,因为示例中的slice指向不同的底层内存,因此需要进行深入分析,并破坏映射访问的速度

即使有一个名为Hasher的接口可以实现并使类型可映射,您的示例仍然需要逐个元素的检查、结果哈希的记忆以及跟踪切片是否已更改的某种方法。我可能会建议你只使用 映射[*ContainerStruct]int并处理这样一个事实:从概念上讲,您可能有两个不同的结构指针,它们的切片成员具有相同的数据


考虑到所有这些,我可能会建议首先重新编译,如果没有的话,可以使用上面Dave C.的建议,以及某种形式的散列值记忆,以及一些跟踪何时需要重新计算的方法。

也许可以使用散列作为键?只有更好。基本上,在您的类型上创建一个方法,返回一些可用的映射键。谢谢Dave,这绝对是一个有效的解决方案。这看起来确实有点骇客,但我不知道有什么更好的方法。链接代码中的骇客只是在如何生成密钥,我只是做了一些丑陋的演示。这取决于您如何为自己的数据集生成每个项的唯一键。如果这不适合您,那么您需要寻找一个替代方案。不幸的是,我在编译时不知道切片的大小,因此这不是这个特定情况下的选项。