我最近在我的一个golang项目中使用了一个地图,它的函数指针就像这样的键:
map[*functiontype] somestructtype
我的一位同事说这是一个坏主意,所以现在我不确定这是否可行。我最初认为没问题,因为方法指针可以检查是否相等并且是不可变的。有人能就此提出一些推理吗?
完整示例:
package main
import "fmt"
type s struct {
string
}
type f func() string
func func1() string { return "func 1" }
func func2() string { return "func 2" }
func main() {
// make two functions and two pointers to them
f1, f2 := func1, func2
p1, p2 := (*f)(&f1), (*f)(&f2)
// make a map of their function pointers
m := make(map[*f]s)
m[p1] = s{"struct 1"}
m[p2] = s{"struct 2"}
// print out the mapping
printmapping(m, p1, p2)
// reverse the pointers and have that printed
p1, p2 = (*f)(&f2), (*f)(&f1)
printmapping(m, p1, p2)
}
func printmapping(m map[*f]s, p1, p2 *f) {
fmt.Println("pointer 1:", m[(*f)(p1)])
fmt.Println("pointer 2:", m[(*f)(p2)])
}
答案 0 :(得分:5)
如果密钥类型是函数类型的指针(例如*func()
),那么它就完全正常了,并且语义符合预期:等于指针是等号键。
但是,查找地图中的值可能无法达到预期效果:example。这里&f
获取局部变量的地址,对于Add
和Find
的不同调用,它永远不会相同。以下当然可能有用:http://play.golang.org/p/F9jyUxzJhz
如果不是一个指针,这是一个坏主意,因为从Go 1开始它是不可能的。根据语言规范(live demo):
必须为键类型的操作数完全定义比较运算符==和!=;因此,键类型不能是函数,映射或切片。
==
和!=
没有为函数定义,因为比较函数的问题是不可判定的。
答案 1 :(得分:4)
你的问题太抽象,没有意义。给我们一个真实例子的代码。 How to create a Minimal, Complete, and Verifiable example.
例如,你的意思是这样吗?
package main
import "fmt"
type f func(int) int
type s struct{ i int }
func f1(i int) int { return i }
func f2(i int) int { return i * i }
func main() {
p1, p2 := f1, f2
fmt.Println(p1, &p1, p2, &p2)
m := make(map[*f]s)
m[(*f)(&p1)] = s{f1(42)}
m[(*f)(&p2)] = s{f2(42)}
fmt.Println(m)
p1, p2 = f2, f1
fmt.Println(m)
fmt.Println(p1, &p1, p2, &p2)
}
输出:
0x20000 0x1040a120 0x20020 0x1040a128
map[0x1040a120:{42} 0x1040a128:{1764}]
map[0x1040a128:{1764} 0x1040a120:{42}]
0x20020 0x1040a120 0x20000 0x1040a128