在Go 1.18 中使用泛型時,您可能會遇到需要建立一個通用函數中自訂類型的新實例。以下問題示範了這項挑戰:
在提供的程式碼範例中,FruitFactory 結構中的 Create 函數旨在建立類型 T 的新實例,但它目前會傳回 nil。這會導致在嘗試存取物件的屬性時出現分段錯誤。
type FruitFactory[T any] struct{} func (f FruitFactory[T]) Create() *T { // How to create non-nil fruit here? return nil } type Apple struct { color string } func example() { appleFactory := FruitFactory[Apple]{} apple := appleFactory.Create() // Panics because nil pointer access apple.color = "red" }
要解決此問題,我們需要修改Create 函數以傳回類型的有效實例T. 有兩種方法可以實現此目的:
方法1(非指標類型)
如果自訂類型不是指標類型(如Apple結構體),您可以宣告類型變數並傳回其位址:
func (f FruitFactory[T]) Create() *T { var a T return &a }
方法2(指標類型)
如果自訂類型是指標類型(如*Apple),解決方案涉及更多。您可以利用類型推斷的強大功能將工廠的類型約束為指針類型:
// Constraining a type to its pointer type type Ptr[T any] interface { *T } // The first type param will match pointer types and infer U type FruitFactory[T Ptr[U], U any] struct{} func (f FruitFactory[T,U]) Create() T { // Declare var of non-pointer type. This is not nil! var a U // Address it and convert to pointer type (still not nil) return T(&a) } type Apple struct { color string } func example() { // Instantiating with ptr type appleFactory := FruitFactory[*Apple, Apple]{} apple := appleFactory.Create() // All good apple.color = "red" fmt.Println(apple) // &{red} }
注意:對於方法2,類型推斷已在Go 1.18 中停用,因此您必須手動指定所有類型參數,例如:FruitFactory[*Apple, Apple]{}。
透過這些修改, Create 函數將傳回類型 T(或 *T)的有效實例,讓您存取其屬性而不會導致分段錯誤。
以上是如何在 Go 1.18 泛型中建立類型化值的非 Nil 物件?的詳細內容。更多資訊請關注PHP中文網其他相關文章!