在Go語言中,創建唯一映射鍵的最有效方法一直是開發者關注的問題。在面對需要保證鍵的唯一性的場景時,我們需要尋找一種高效且可靠的方法。 php小編草將在本文中分享一種最有效的方法,幫助您在Go語言中建立唯一映射鍵,讓您的程式碼更加優化和高效。無論是處理大規模資料還是實現高並發的應用,這些方法都能幫助您提高效能和效率。讓我們一起來了解吧!
我在圖書館的某個地方有一個 map[any]SomeType
。我希望庫使用者能夠為該地圖建立鍵,以便保證它們在單一應用程式執行中不會發生衝突,並且我希望這些鍵能夠有效地進行地圖查找。
首先想到的是使用某個唯一的空物件的記憶體位址。但到目前為止我嘗試的一切都失敗了:
<code>package main import "fmt" var key1 = &struct{}{} var key2 = &struct{}{} var key3 = struct{}{} var key4 = struct{}{} var key5 = new(struct{}) var key6 = new(struct{}) func main() { fmt.Println("key1 == key2", key1 == key2) fmt.Println("key3 == key4", &key3 == &key4) fmt.Println("key5 == key6", key5 == key6) test(key1, key2, "func12") test(&key3, &key4, "func34") test(key5, key6, "func56") } func test(a, b any, msg string) { fmt.Println(msg, a == b) } </code>
列印
key1 == key2 true key3 == key4 false key5 == key6 true func12 true func34 true func56 true
因此,取得空結構變數的位址幾乎是可行的,直到將其傳遞給函數為止。然後差別就消失了。
我不想引入密鑰註冊表,因為它是一個不必要的複雜化。我也不想使用字串,因為庫的不同用戶需要協商金鑰或使用名稱空間,並且需要散列和比較字串也是不必要的複雜化。
有沒有我沒想到的方法?
標準函式庫在使用context.Context
時使用了一個「技巧」:上下文能夠在其中攜帶任意值,並且這些值使用 interface{}
進行鍵控(從一段時間以來any
)1。然後,您自己的套件可以為其將要使用的上下文鍵定義一個新的未匯出類型,然後定義一組具有該類型的常數作為該套件已知的上下文鍵。現在的技巧是,類型始終是 interface{}
類型的任何值的一部分,因此不可能建立與套件的鍵衝突的介面值。
基本上是這樣的:
package mypkg type contextKey int const ( KeyFoo = contextKey(iota) KeyBar )
現在,當您執行key interface{} = KeyFoo
時,幾乎可以保證程式中任何其他程式碼片段都不能具有與key
相同的值,因為其中一部分將(指向的內部指標)未匯出輸入contextKey
。
您可能需要閱讀這篇經典文章來了解其工作原理(雖然有點生疏,但仍然有 99% 的正確性) )。
對我來說,這看起來是一種前進的方式:您的包的用戶可以生成自己的密鑰並將其提交到您的地圖,該地圖的密鑰類型應為interface {}
或any
。無需由集中式註冊表來移交這些金鑰。
1 請參閱 context.Context.Value() 和 context.WithValue() 以了解更多資訊。後者提供了有關如何產生金鑰的更多提示。
以上是在 Go 中建立唯一映射鍵的最有效方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!