亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在 go 中為哈希映射創建復合鍵

如何在 go 中為哈希映射創建復合鍵

Go
尚方寶劍之說 2023-04-04 15:09:11
首先,我對組合鍵的定義——兩個或多個值組合起來構成鍵。不要與數據庫中的復合鍵混淆。我的目標是將 的計算值保存pow(x, y)在哈希表中,其中x和y是整數。這是我需要關于如何制作密鑰的想法的地方,以便給定x和y,我可以在哈希表中查找它,找到pow(x,y).例如:pow(2, 3) => {key(2,3):8}我想弄清楚的是如何獲取 pair 的映射鍵(2,3),即生成一個鍵的最佳方法,該鍵是多個值的組合,并在哈希表中使用它。
查看完整描述

3 回答

?
慕村9548890

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}])

輸出是一樣的。



查看完整回答
反對 回復 2023-04-04
?
寶慕林4294392

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])

}

我希望這有幫助


查看完整回答
反對 回復 2023-04-04
?
侃侃爾雅

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 個非常相似的映射字段的結構。


查看完整回答
反對 回復 2023-04-04
  • 3 回答
  • 0 關注
  • 191 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號