我正在嘗試使用 Go 泛型來撰寫一個函式來減少我們代碼中的一些樣板 if/else 塊。我想出了適用于單個型別引數的方法,如下所示:
func valueOrNil[T *int](value T) any {
if value == nil {
return nil
}
return *value
}
雖然這很好用,但它并不是真正有用,因為它只允許*int,并且我希望此代碼可以與任何原始型別一起使用。我試圖擴展它以支持第二種型別,如下所示:
func valueOrNil[T *int | *uint](value T) any {
if value == nil {
return nil
}
return *value
}
但是,此變體因編譯器錯誤而失敗:
invalid operation: pointers of value (variable of type T constrained by *int|*uint) must have identical base types
誰能發現我在這里做錯了什么,或者這樣的事情只是“不支持”?
uj5u.com熱心網友回復:
問題似乎在于您試圖通過指向型別而不是型別本身的指標來通用。如果我們將指標移動到引數本身而不是型別引數上,它就可以作業。
解釋如下,但這里是作業代碼:
func valueOrNil[T ~int | ~uint](value *T) T {
if value == nil {
var zero T
return zero
}
return *value
}
所以代替這個(這不起作用):
func valueOrNil[T *int | *uint](value T) any
你可以這樣做:
func valueOrNil[T int | uint](value *T) any
但是,您可能希望更進一步并處理底層型別:
func valueOrNil[T ~int | ~uint](value *T) any
這將允許自定義型別與函式一起使用:
type Thing int
var thing Thing
println(valueOrNil(thing))
您可能要考慮的另一個方面是對回傳型別也是通用的。您可以使用相同的T引數來執行此操作。
例如:
func valueOrNil([T ~int | ~uint](value *T) T
但這意味著您需要更改部分實作。而不是這個:
if value == nil {
return nil
}
你可以這樣做:
if value == nil {
var zero T
return zero
}
uj5u.com熱心網友回復:
我從Miquella接受的答案(感謝您的見解;我也學到了一些關于 的用法)使我意識到,一旦將移到引數型別上,我實際上并不需要指定特定型別,所以這就是我最終得到:~*
func valueOrNil[T any](value *T) any {
if value == nil {
return nil
}
return *value
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/450158.html
