将函数指针用作go中的键的映射

将函数指针用作go中的键的映射,go,Go,我最近在我的一个golang项目中使用了一个map,它将函数指针作为键,如下所示: map[*functiontype] somestructtype 我的一位同事说这是个坏主意,所以现在我不确定这是否可行。我最初认为它是可以的,因为方法指针可以检查是否相等,并且是不可变的。有人能就这件事提供一些理由吗 完整示例: package main import "fmt" type s struct { string } type f func() string func func1(

我最近在我的一个golang项目中使用了一个map,它将函数指针作为键,如下所示:

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)])
}
如果键类型是指向函数类型的指针(例如
*func()
),那么它完全可以,语义与预期的一样:相等的指针就是相等的键

但是,在映射中查找值可能不会像您预期的那样成功:。这里
&f
获取局部变量的地址,对于
Add
Find
的不同调用,该地址永远不会相同。当然,以下内容可能有用:


如果它不是指针,这是一个坏主意,因为从Go 1开始它是不可能的。根据语言规范():

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


==
=没有为函数定义,因为比较函数是否相等的问题是无法确定的。

您的问题太抽象,没有意义。给我们一个真实例子的代码

例如,你的意思是这样的吗

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

很抱歉,在我的示例中,我最初省略了functiontype之前的星号。那么上面的内容(刚刚编辑过)真的可以吗?@peterhomel它在技术上没有问题,尽管很难想象你为什么想要一个指向函数的指针。你认为什么问题需要这种间接处理?注意,Go中指向函数的指针与C中的函数指针不同;它们更类似于C中指向函数指针的指针。我在插件系统中将它们用作处理程序回调。只是想从外部将一些数据附加到此回调的每个实例,因此使用了这种类型的构造。@Peterhomel如何获取指针以查找映射中的值?或者你只是使用映射进行迭代吗?是的,目前正是这样。这不完全是我的意思,而是一个完整示例的良好起点。只要重写它,使我坚持我的问题,并纳入我的问题。谢谢。。。