你不能在map中使用函数作为键:密钥类型必须是可比较的。 Go blog: Map键可以是任何可比较的类型。语言规范对此进行了精确的定义,但简而言之,类似的类型是布尔型、数值型、字符串型、指针型、通道型和接口型,以及只包含这些类型的结构或数组。值得注意的是,列表中没有切片、Map和函数;这些类型不能使用==进行比较,也不能用作Map键 根据您的具体用例,您可能使用的是一个接口。
package main
import "fmt"
func a(i int) int {
return i + 1
}
func b(i int) int {
return i + 2
}
type Function func(int)int
type FunctionWrapper struct {
f *Function
}
var fnMap = make(map[string]FunctionWrapper)
// MakeFunctionWrapper returns a unique FunctionWrapper per Function pointer, using fnMap to avoid having multiple values for the same function
func MakeFunctionWrapper(f Function) FunctionWrapper {
key := fmt.Sprintf("%#v", f)
data, ok := fnMap[key]
if !ok {
data = FunctionWrapper{&f}
fnMap[key] = data
}
return data
}
func main() {
functions := make(map[FunctionWrapper]bool)
fa := MakeFunctionWrapper(a)
fb := MakeFunctionWrapper(b)
fb2 := MakeFunctionWrapper(b)
functions[fa] = true
functions[fb] = true
functions[fb2] = false // This overwrites the previous value since fb is essentially the same as fb2
fmt.Println(functions[fa]) // "true"
fmt.Println(functions[fb]) // "false"
fmt.Println(functions[fb2]) // "false"
}
package main
import (
"fmt"
)
type Action func()
var Premises = make(map[*Action][]*Action)
func OnSetup(action Action, premises ...*Action) *Action {
ap := &action
Premises[ap] = premises
return ap
}
func rank(action *Action) int {
if len(Premises[action]) == 0 {
return 0
}
max := 0
for _, p := range Premises[action] {
r := rank(p)
if r > max {
max = r
}
}
return max + 1
}
func Setup() {
ranks := make(map[int][]*Action)
for action := range Premises {
r := rank(action)
ranks[r] = append(ranks[r], action)
}
for r := 0; r < len(ranks); r++ {
fmt.Println("Rank:", r)
actions := ranks[r]
for a := range actions {
(*(actions[a]))()
}
}
}
func main() {
a := OnSetup(func() { fmt.Println("a") })
b := OnSetup(func() { fmt.Println("b") }, a)
OnSetup(func() { fmt.Println("c") }, b)
OnSetup(func() { fmt.Println("d") })
Setup()
}
8条答案
按热度按时间2w2cym1i1#
不能将函数用作Map键。语言规范明确指出:
比较运算符==和!=必须为键类型的操作数完全定义;因此,密钥类型不能是函数、Map或切片。
y53ybaqx2#
可以使用
reflect
。fafcakar3#
你不能在map中使用函数作为键:密钥类型必须是可比较的。
Go blog:
Map键可以是任何可比较的类型。语言规范对此进行了精确的定义,但简而言之,类似的类型是布尔型、数值型、字符串型、指针型、通道型和接口型,以及只包含这些类型的结构或数组。值得注意的是,列表中没有切片、Map和函数;这些类型不能使用==进行比较,也不能用作Map键
根据您的具体用例,您可能使用的是一个接口。
hgncfbus4#
虽然函数不能是键,但函数指针可以。
http://play.golang.org/p/9DdhYduX7E
64jmpszr5#
函数不能是键:
比较运算符==和!=必须为键类型的操作数完全定义;因此,密钥类型不能是函数、Map或切片。
来源
6ss1mwsb6#
你不能直接这样做,正如前面提到的,但是你可以假装你做了这样的事情:
Check it out on the Go playground
这有点麻烦,老实说,我认为本质上使用指针的字符串版本作为Map的键是一个非常糟糕的主意。但如果你真的需要的话这至少是个选择
3df52oht7#
一种简单的方法是将函数 Package 在
struct
中,然后使用指向此结构体的指针作为map键:e1xvtsh38#
使用函数指针作为Map键而不是函数。
下面的示例将函数的依赖项存储在Map中,计算执行顺序并以正确的顺序执行函数: