首頁 >後端開發 >Golang >如何在 Go 1.18 泛型中建立類型化值的非 Nil 物件?

如何在 Go 1.18 泛型中建立類型化值的非 Nil 物件?

Patricia Arquette
Patricia Arquette原創
2024-12-10 08:11:12153瀏覽

How to Create a Non-Nil Object of a Typed Value in Go 1.18 Generics?

透過Go 建立類型化值的新物件(go 1.18)泛型

在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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn