一组包含切片的结构体。

huangapple go评论71阅读模式
英文:

Set of structs containing a slice

问题

我正在尝试实现一个玩具搜索算法,并需要维护一组已探索的状态。一个状态是一个结构体:

type VWState struct {
    botLocation   VWCoords
    dirtLocations []VWCoords
}

我的第一个想法是可以使用map[VWState]bool来实现一个简单的集合,但是我似乎无法找到一种方法使其工作。如果我尝试将VWState用作映射的键,我会得到以下错误:

Panic: runtime error: hash of unhashable type vw.VWState (PC=0x40EB0D)

有没有办法使其工作?我可以为结构体实现一个自定义的哈希函数,还是应该考虑其他实现方式?

非常感谢任何帮助!

英文:

I'm trying to implement a toy search algorithm and need to maintain a set of explored states. A state is a struct:

type VWState struct {
    botLocation   VWCoords
    dirtLocations []VWCoords
}

My first thought was that a simple Set could be implemented using a map[VWState]bool, but I can't seem to figure out a way to make it work. If I try to use a VWState as a key to a map, I get the following panic:

Panic: runtime error: hash of unhashable type vw.VWState (PC=0x40EB0D)

Is there a way to make this work? Can I implement a custom hashing function for the struct, or should I be looking at some other ways to implement this?

Any help would be greatly appreciated.

答案1

得分: 4

你可以使用指向你的结构体的指针作为地图的键:

map[*VWState]bool

如果你想要比较等效的结构体,你可以创建一个方法来输出地图的键。String() 方法会很方便,因为你还可以用它来打印你的结构体,或者结合一个哈希函数输出一些更短的东西,甚至是一个 int

下面的代码可能已经足够简单了,但如果你愿意,你可以使输出更短(在格式化行中要小心不要递归调用 String()):

func (s VWState) String() string {
    return fmt.Sprintf("%#v", s)
}

func main() {
    m := make(map[string]bool)
    s := VWState{}
    m[s.String()] = true
}
英文:

You can use a pointer to your struct as a map key:

map[*VWState]bool

If you want to be able to compare equivalent structs, you can create a method to output a key for the map. String() would be convenient, since you could also use it to print your struct, or tie in a hash function and output something shorter, even an int.

Something as simple as this may suffice, though you could make the output shorter if you like (being careful not to recursively call String() in your format line):

func (s VWState) String() string {
	return fmt.Sprintf("%#v", s)
}

func main() {
	m := make(map[string]bool)
	s := VWState{}
	m[s.String()] = true
}

答案2

得分: 1

如果dirtLocations有一个合理的最大长度限制,你可以使用数组而不是切片。数组是可哈希的(前提是元素是可哈希的)。

type VWState struct {
    botLocation   VWCoords
    dirtLocations [4]VWCoords
}

然后,你需要添加一个有效的dirtLocations计数,或者检测VWCoords的零值来确定dirtLocations中有多少个有效的插槽。

英文:

If there is a sensible maximum length for dirtLocations then you could use an array instead of a slice. Arrays are hashable (provided the element is hashable).

type VWState struct {
	botLocation   VWCoords
	dirtLocations [4]VWCoords
}

You'll then need to either add a count of the number of valid dirtLocations or detect the zero value of VWCoords to work out how many slots in dirtLocations are valid.

huangapple
  • 本文由 发表于 2014年10月21日 05:33:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/26475310.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定