将函数指针映射为go中的键

时间:2015-04-20 12:32:55

标签: go

我最近在我的一个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)])
}

2 个答案:

答案 0 :(得分:5)

如果密钥类型是函数类型的指针(例如*func()),那么它就完全正常了,并且语义符合预期:等于指针是等号键。

但是,查找地图中的值可能无法达到预期效果:example。这里&f获取局部变量的地址,对于AddFind的不同调用,它永远不会相同。以下当然可能有用: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