1 回答

TA貢獻1862條經驗 獲得超6個贊
這種條件類型不能用泛型很好地解決,因為當你用它實例化時T any,*Foo你會丟失關于基類型的信息。事實上,您的代碼仍然使用反射和any(= interface{}),并且makeN函數的返回類型必須被類型斷言為*Foo.
您可以使用當前代碼獲得的最接近的是:
func makeNew[T any](v T) func() any {
if typ := reflect.TypeOf(v); typ.Kind() == reflect.Ptr {
elem := typ.Elem()
return func() any {
return reflect.New(elem).Interface() // must use reflect
}
} else {
return func() any { return new(T) } // v is not ptr, alloc with new
}
}
然后兩個 maker 函數將返回一個any包裝非 nil*Foo值的:
fmt.Printf("%T, %v\n", make1(), make1()) // *main.Foo, &{}
fmt.Printf("%T, %v\n", make2(), make2()) // *main.Foo, &{}
游樂場:https ://gotipplay.golang.org/p/kVUM-qVLLHG
進一步的考慮:
return makeNewA[T]在您的第一次嘗試中不起作用,因為條件reflect.TypeOf(v).Kind() == reflect.Ptr是在運行時評估的,而實例化makeNewA發生在編譯時。在編譯時T僅受約束any并且any(= interface{}) 未實現Ptr[U]
您無法僅使用參數捕獲有關指針類型和基類型的信息v。例如makeNew[T Ptr[U], U any](v T),調用 with 時不會編譯,調用 with時makeNew(Foo{})將makeNew[T Ptr[U], U any](v U)推斷T為**Foo*Foo
- 1 回答
- 0 關注
- 150 瀏覽
添加回答
舉報