php小編西瓜將為您介紹如何在Go語言中使用泛型實例化類型參數的非零指標。在Go語言中,泛型是一種強大的特性,可以增加程式碼的靈活性和重複使用性。當我們需要在泛型函數或方法中實例化一個非零指標時,可以使用型別斷言和反射來實現。透過使用這些技術,我們可以在運行時根據類型參數的具體類型來建立一個非零指標實例,從而實現泛型的靈活性和通用性。下面我們來詳細了解具體的實作方法。
問題內容
現在 golang/go:master
上提供了類型參數,我決定嘗試一下。看來我遇到了在類型參數提案中找不到的限制。 (或者我一定錯過了)。
我想寫一個函數,它傳回帶有介面類型約束的泛型類型值的切片。如果傳遞的類型是帶有指標接收器的實現,我們如何實例化它?
type SetGetter[V any] interface { Set(V) Get() V } // SetGetterSlice turns a slice of type V into a slice of type T, // with T.Set() called for each entry in values. func SetGetterSlice[V any, T SetGetter[V]](values []V) []T { out := make([]T, len(values)) for i, v := range values { out[i].Set(v) // panic if T has pointer receiver! } return out }
當使用*Count
類型作為T
呼叫上述SetGetterSlice()
函數時,此程式碼將在呼叫Set(v)
時出現混亂。 (Go2go 遊樂場)毫不奇怪,因為基本上程式碼創建了 nil
指標的切片:
// Count implements SetGetter interface type Count struct { x int } func (c *Count) Set(x int) { c.x = x } func (c *Count) Get() int { return c.x } func main() { ints := []int{1, 2, 3, 4, 5} sgs := SetGetterSlice[int, *Count](ints) for _, s := range sgs { fmt.Println(s.Get()) } }
同一問題的變體
這個想法行不通,我似乎找不到任何簡單的方法來實例化指向的值。
-
out[i] = new(T)
將導致編譯失敗,因為它傳回*T
,其中類型檢查器希望查看T
。 - 呼叫
*new(T)
進行編譯,但會導致相同的執行時間恐慌,因為new(T)
傳回**Count
在這種情況下,其中指向Count
的指標仍然是nil
。 - 將傳回類型變更為指向
T
的指標片段將導致編譯失敗:
func SetGetterSlice[V any, T SetGetter[V]](values []V) []*T { out := make([]*T, len(values)) for i, v := range values { out[i] = new(T) out[i].Set(v) // panic if T has pointer receiver } return out } func main() { ints := []int{1, 2, 3, 4, 5} SetGetterSlice[int, Count](ints) // Count does not satisfy SetGetter[V]: wrong method signature }
解決方法
到目前為止我發現的唯一解決方案是要求將建構函數傳遞給泛型函數。但這感覺不對,而且有點乏味。如果 func F(T interface{})() []T
是完全有效的語法,為什麼需要這樣做?
func SetGetterSlice[V any, T SetGetter[V]](values []V, constructor func() T) []T { out := make([]T, len(values)) for i, v := range values { out[i] = constructor() out[i].Set(v) } return out } // ... func main() { ints := []int{1, 2, 3, 4, 5} SetGetterSlice[int, *Count](ints, func() *Count { return new(Count) }) }
摘要
我的問題(按優先順序排列):
- 我是否忽略了一些顯而易見的事情?
- 這是 Go 中泛型的限制嗎?這已經是最好的了嗎?
- 此限制是否已知,或者我應該在 Go 專案中提出問題嗎?
解決方法
基本上,您必須在約束中新增一個類型參數,以使 T
可轉換為其指標類型。在最基本的形式中,該技術如下所示(帶有匿名約束):
func Foo[T any, PT interface { *T; M() }]() { p := PT(new(T)) p.M() // calling method on non-nil pointer }
遊樂場:https://www.php.cn/link/24aef8cb3281a2422a59b51659f1ad2e
#逐步解決方案
#您的限制 SetGetter
已經宣告了型別參數 V
,因此我們稍微修改上面的範例:
// V is your original type param // T is the additional helper param type SetGetter[V any, T any] interface { Set(V) Get() V *T }
接著定義 SetGetterSlice
函數,其型別參數為 T any
,其目的只是實例化限制 SetGetter
。
然後您就可以將表達式 &out[i]
轉換為指標類型,並成功呼叫指標接收器上的方法:
// T is the type with methods with pointer receiver // PT is the SetGetter constraint with *T func SetGetterSlice[V any, T any, PT SetGetter[V, T]](values []V) []T { out := make([]T, len(values)) for i, v := range values { // out[i] has type T // &out[i] has type *T // PT constraint includes *T p := PT(&out[i]) // valid conversion! p.Set(v) // calling with non-nil pointer receiver } return out }
完整程式:
CFE57E536C89530D9A8C38E10967A10D這變得更加冗長,因為SetGetterSlice
現在需要三個型別參數:原始V
加上#T
(有指標接收器的型別)和PT
(新限制)。然而,當您呼叫函數時,您可以省略第三個- 透過型別推斷,實例化PT SetGetter[V,T]
所需的型別參數V
和T
都是已知的:
SetGetterSlice[int, Count](ints)
遊樂場:https://www.php.cn/link/6b061fc28f7473418a006dfa832708b1
#以上是如何使用泛型 Go 實例化型別參數的非零指標?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

goimpactsdevelopmentpositationality throughspeed,效率和模擬性。 1)速度:gocompilesquicklyandrunseff,IdealforlargeProjects.2)效率:效率:ITScomprehenSevestAndardArdardArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdEcceSteral Depentencies,增強的Depleflovelmentimency.3)簡單性。

C 更適合需要直接控制硬件資源和高性能優化的場景,而Golang更適合需要快速開發和高並發處理的場景。 1.C 的優勢在於其接近硬件的特性和高度的優化能力,適合遊戲開發等高性能需求。 2.Golang的優勢在於其簡潔的語法和天然的並發支持,適合高並發服務開發。

Golang在实际应用中表现出色,以简洁、高效和并发性著称。1)通过Goroutines和Channels实现并发编程,2)利用接口和多态编写灵活代码,3)使用net/http包简化网络编程,4)构建高效并发爬虫,5)通过工具和最佳实践进行调试和优化。

Go語言的核心特性包括垃圾回收、靜態鏈接和並發支持。 1.Go語言的並發模型通過goroutine和channel實現高效並發編程。 2.接口和多態性通過實現接口方法,使得不同類型可以統一處理。 3.基本用法展示了函數定義和調用的高效性。 4.高級用法中,切片提供了動態調整大小的強大功能。 5.常見錯誤如競態條件可以通過gotest-race檢測並解決。 6.性能優化通過sync.Pool重用對象,減少垃圾回收壓力。

Go語言在構建高效且可擴展的系統中表現出色,其優勢包括:1.高性能:編譯成機器碼,運行速度快;2.並發編程:通過goroutines和channels簡化多任務處理;3.簡潔性:語法簡潔,降低學習和維護成本;4.跨平台:支持跨平台編譯,方便部署。

關於SQL查詢結果排序的疑惑學習SQL的過程中,常常會遇到一些令人困惑的問題。最近,筆者在閱讀《MICK-SQL基礎�...

golang ...


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

Atom編輯器mac版下載
最受歡迎的的開源編輯器

SublimeText3 Linux新版
SublimeText3 Linux最新版

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),