3 回答

TA貢獻1884條經驗 獲得超4個贊
最簡單和最靈活的方法是使用 astruct作為鍵類型,包括您希望成為鍵一部分的所有數據,因此在您的情況下:
type Key struct {
? ? X, Y int
}
就這樣。使用它:
m := map[Key]int{}
m[Key{2, 2}] = 4
m[Key{2, 3}] = 8
fmt.Println("2^2 = ", m[Key{2, 2}])
fmt.Println("2^3 = ", m[Key{2, 3}])
輸出(在Go Playground上嘗試):
2^2?=??4 2^3?=??8
規范:映射類型:您可以使用任何類型作為比較運算符==
和!=
完全定義的鍵,上面的Key
結構類型實現了這一點。
規范:比較運算符:如果結構值的所有字段都是可比較的,則結構值是可比較的。如果兩個結構值對應的非空白字段相等,則它們相等。
一件重要的事情:你不應該使用指針作為鍵類型(例如*Key
),因為比較指針只比較內存地址,而不是指向的值。
另請注意,您也可以使用數組(不是slices)作為鍵類型,但數組不如結構靈活。您可以在此處閱讀
這就是數組的樣子:
type Key [2]int
m := map[Key]int{}
m[Key{2, 2}] = 4
m[Key{2, 3}] = 8
fmt.Println("2^2 = ", m[Key{2, 2}])
fmt.Println("2^3 = ", m[Key{2, 3}])
輸出是一樣的。

TA貢獻2021條經驗 獲得超8個贊
Go 無法對一片整數進行散列。
因此,我采用的方法是將結構映射到數字。
這是一個如何做到這一點的例子:
package main
import (
"fmt"
)
type Nums struct {
num1 int
num2 int
}
func main() {
powers := make(map[Nums]int)
numbers := Nums{num1: 2, num2: 4}
powers[numbers] = 6
fmt.Printf("%v", powers[input])
}
我希望這有幫助

TA貢獻1801條經驗 獲得超16個贊
其他答案很好地解決了您的具體問題。我想添加一個在某些極端情況下可能有用的額外技巧。
鑒于映射鍵必須是可比較的,您還可以使用接口。如果接口的動態值是可比較的,則接口是可比較的。
這允許您從本質上對映射進行分區,即在同一數據結構中使用多種類型的鍵。例如,如果您想在地圖中存儲 n 元組(它不適用于數組,因為數組長度是類型的一部分)。
這個想法是用一個虛擬方法定義一個接口(但它肯定不是虛擬的),并將其用作映射鍵:
type CompKey interface {
? ? isCompositeKey() bool
}
var m map[CompKey]string
此時,您可以讓任意類型實現接口,無論是顯式實現還是僅通過嵌入實現。
在這個例子中,想法是使接口方法不被導出,這樣其他結構就可以嵌入接口而不必提供實際的實現——不能從其包外部調用該方法。它只會發出該結構可用作復合映射鍵的信號。
type AbsoluteCoords struct {
? ? CompKey
? ? x, y int
}
type RelativeCoords struct {
? ? CompKey
? ? x, y int
}
func foo() {
? ? p := AbsoluteCoords{x: 1, y: 2}
? ? r := RelativeCoords{x: 10, y: 20}
? ? m[p] = "foo"
? ? m[r] = "bar"
? ? fmt.Println(m[AbsoluteCoords{x: 10, y: 20}]) // "" (empty, types don't match)
? ??
? ? fmt.Println(m[RelativeCoords{x: 10, y: 20}]) // "bar" (matches, key present)
}
當然,沒有什么能阻止您在界面上聲明實際的方法,這在遍歷地圖鍵時可能很有用。
這個接口鍵的缺點是現在你有責任確保實現類型實際上是可比較的。例如這個地圖鍵會恐慌:
type BadKey struct {
? ? CompKey
? ? nonComparableSliceField []int
}
b := BadKey{nil, []int{1,2}}
m[b] = "bad!" // panic: runtime error: hash of unhashable type main.BadKey
總而言之,當您需要在同一映射中保留兩組 K/V 對時,這可能是一種有趣的方法,例如,為了保持函數簽名的完整性或避免定義具有 N 個非常相似的映射字段的結構。
- 3 回答
- 0 關注
- 191 瀏覽
添加回答
舉報