php小編柚子將為大家解答一個常見的問題:在建構子的泛型參數中,無法推論出類型的原因。在PHP中,泛型參數的類型推論是透過參數的預設值來實現的。然而,在建構函式中,由於參數是在物件建立之前就被傳入的,因此無法透過物件的實例來推斷參數的類型。這就導致了建構函式中無法推斷出泛型參數的類型,需要手動指定型別來解決這個問題。
我在 go 中有一些通用程式碼,其中有一個具有通用參數的「主」類型和許多應該共享相同通用參數的「從」類型。程式碼看起來與此類似:
type Doer[T any] interface { ModifyA(*A[T]) } type B[T any] struct { } func NewB[T any]() *B[T] { return new(B[T]) } func (b *B[T]) ModifyA(a *A[T]) { // Do a thing } type A[T any] struct{} func NewA[T any]() A[T] { return A[T]{} } func (a *A[T]) Run(doers ...Doer[T]) { for _, doer := range doers { doer.ModifyA(a) } } func main() { a := new(A[int]) a.Run(NewB()) // error here }
基本上,使用者應該在 a
上定義 t
,然後 b
上的 t
應該是相同的。此類程式碼可以在支援泛型的其他語言中工作,但在 go 中,我在註解行處收到 cannot infer t
編譯錯誤(請參閱此處的 go playground 程式碼)。在我看來, a
上的類型參數設定為 int
,因此 b
上的類型參數也應設定為 int
。我可以改為呼叫 newb[int]()
,但這對我來說似乎太冗長。為什麼會出現這種情況?
這是「為什麼編譯器不能根據傳回類型的使用方式推斷類型參數?」的變體。答:因為從 go 1.20 開始,這不是類型推論的工作方式。
型別推論適用於:
如果您一一檢查這些規則:
newb()
有型別參數清單嗎?不。您在呼叫它時沒有指定類型參數。
是否有其他已知的型別參數可以用來推論其他型別參數?不,您根本沒有提供任何類型參數。請注意,這種情況適用於您提供部分數量的類型參數的函數調用,例如:
func foo[T any, U *T]() {}
在上面您只能提供t
,例如float64
,編譯器將使用t -> float64
建構替換映射,然後推斷 u -> *float64
#最後,有普通函數參數的列表嗎?否。 newb
為空。
僅此而已。編譯器不會根據函數傳回類型的使用方式推斷類型參數。
在撰寫本文時,正在討論的相關提案有:
以上是無法推斷函數建構函數的泛型參數中的類型的詳細內容。更多資訊請關注PHP中文網其他相關文章!