Golang 1.18beta 支持泛型,我想在泛型切片上添加擴展方法。例如,映射函式定義如下:
func Map[E, V any](slice *[]E, iteratee func(E) V) *[]V {
result := []V{}
for _, item := range *slice {
result = append(result, iteratee(item))
}
return &result
}
然后我想把這個方法做為 slice 的擴展方法,類似這樣,但無法編譯成功:
func (slice *[]E) Map[E, V any](iteratee func(E) V) *[]V {
result := []V{}
for _, item := range *slice {
result = append(result, iteratee(item))
}
return &result
}
實作第二個代碼塊的正確方法是什么?
我想這樣使用:
slice := []string{"a", "b", "c"}
newSlice := slice.Map(func(s string) string {
return s "122"
})
uj5u.com熱心網友回復:
您必須slice使用要用于Map()(或任何其他)方法的型別引數宣告型別:
type slice[E, V any] []E
而且您必須將型別引數添加到接收器,沒有約束(這些將與型別宣告中定義的相同),就好像您要實體化泛型slice型別一樣:
func (s *slice[E, V]) Map(iteratee func(E) V) *[]V {
result := []V{}
for _, item := range *s {
result = append(result, iteratee(item))
}
return &result
}
測驗它:
s := slice[int, string]{1, 2, 3}
m := s.Map(func(i int) string { return fmt.Sprint("x", i) })
fmt.Println(m)
哪個會輸出(在Go Playground上試試):
&[x1 x2 x3]
另請注意,切片(切片標頭)已經包含指向底層陣列的指標,因此您很少需要使用指向切片的指標。而是用非指標接收器宣告該方法,并回傳一個非指標(在Go Playground上試試這個):
func (s slice[E, V]) Map(iteratee func(E) V) []V {
result := []V{}
for _, item := range s {
result = append(result, iteratee(item))
}
return result
}
(提示)規范中的相關部分:規范:方法宣告:
如果接收器基型別是引數化型別,則接收器規范必須宣告相應的型別引數以供方法使用。這使得接收器型別引數可用于該方法。
從語法上講,這個型別引數宣告看起來像接收器基型別的實體化,除了型別引數是被宣告的型別引數,一個接收器基型別的每個型別引數。型別引數名稱不需要與接收者基型別定義中對應的引數名稱匹配,并且所有非空白引數名稱在接收者引數部分和方法簽名中必須是唯一的。接收器型別引數約束由接收器基型別定義隱含:對應的型別引數有對應的約束。
uj5u.com熱心網友回復:
然后我想把這個方法作為 slice 的擴展方法
無論有沒有泛型,您都無法做到這一點。您只能在命名型別上定義方法,并且在您的第二個片段中,E它不是型別,而是型別引數。
在 Go 中,切片本身不是命名型別,這是在其上宣告方法的必要條件。與具有原型的 Javascript 不同,Go 中的切片型別必須是某物的切片,即已定義的型別,以便在其上有方法。事實上,它在語言規范中正式定義為:
SliceType = "[" "]" ElementType .
因此,您不能在任何和所有 slices 上定義方法。您可以在命名切片型別上宣告方法,然后可以對其進行引數化。
但是為了使用第二種型別 param V,它必須在型別宣告中定義。方法不允許具有未在接收器型別上指定的型別引數。例如:
type Slice[T, V any] []T
func (s Slice[T,V]) Map(iteratee func(T) V) []V {
result := make([]V, 0)
for _, item := range s {
result = append(result, iteratee(item))
}
return result
}
但在這一點上,您不妨繼續使用泛型函式,該函式具有允許型別推斷的優點,從而允許您在實體化期間減少冗長的代碼并省略顯式型別引數。
游樂場展示方法與功能:https : //gotipplay.golang.org/p/R7uAq0SBUjj
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/408802.html
標籤:
上一篇:processDebugMainManifestFAILED,我在使用targetSdkVersion作為31時遇到此錯誤
下一篇:檢查泛型中的地圖資料型別
