2014-12-03 24 views
6

如何使用功能作爲地圖的鍵?例如:Golang如何使用功能作爲地圖的鍵

type Action func(int) 
func test(a int) { } 
func test2(a int) { } 

func main() { 
    x := map[Action]bool{} 
    x[test] = true 
    x[test2] = false 
} 

這些代碼會顯示一個錯誤:invalid map key type Action

+0

有什麼確切的使用情況?接口不會更具語義和更可擴展性嗎? – 2014-12-03 08:45:58

+0

我需要知道,我從'trie'獲得的函數是否是由函數'X'創建的函數。 – Kokizzu 2014-12-03 10:58:46

回答

2

你不能直接這樣做,因爲已經提到的,但你可以排序假的,你做這樣的事情:

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" 
} 

Check it out on the Go playground

這有點麻煩,我真的認爲從根本上使用指針的字符串版本作爲地圖的關鍵是一個非常糟糕的主意。但是......如果你真的需要它,這至少是一種選擇。

+0

只有您保留函數包裝器實例並始終重新使用它們。在同一個函數中創建2個包裝並不會產生相同的結果:http://play.golang.org/p/DdwzCTORBf – chakrit 2015-04-04 02:25:36

+1

這不好...我會更新我的回覆。 – Nerdmaster 2015-04-06 16:16:16

11

不能使用的功能作爲地圖的關鍵。該language specification明確表示:

The comparison operators == and != must be fully defined for operands of the key type; thus the key type must not be a function, map, or slice.

7

無法使用的功能在地圖鍵:鍵類型必須是可比的。

Go blog

map keys may be of any type that is comparable. The language spec defines this precisely, but in short, comparable types are boolean, numeric, string, pointer, channel, and interface types, and structs or arrays that contain only those types. Notably absent from the list are slices, maps, and functions; these types cannot be compared using ==, and may not be used as map key

什麼,你可以使用,這取決於您的具體的使用情況,是一個接口。

4

函數不能鍵:

The comparison operators == and != must be fully defined for operands of the key type; thus the key type must not be a function, map, or slice.

Source

2

雖然函數不能是鍵,但函數指針可以。

package main 

import "fmt" 

type strFunc *func() string 

func main() { 

    myFunc := func() string { return "bar" } 
    m := make(map[strFunc]string) 
    m[(strFunc)(&myFunc)] = "f" 

    for f, name := range m { 
     fmt.Println((*f)(), name) 
    } 
} 

http://play.golang.org/p/9DdhYduX7E

+0

這隻適用於你使用變量的地址,它與「函數指針」不一樣。下面是您的示例,將相同的函數分配給另一個變量,並且生成的映射有兩個條目,因爲變量地址不同:https://play.golang.org/p/8DBIR4h1jU – 2017-03-03 21:16:07