Home >Backend Development >Golang >How Can I Safely Create Typed Objects of a Generic Type in Go Using Generics?

How Can I Safely Create Typed Objects of a Generic Type in Go Using Generics?

Barbara Streisand
Barbara StreisandOriginal
2024-12-08 06:55:10850browse

How Can I Safely Create Typed Objects of a Generic Type in Go Using Generics?

Creating Typed Objects with Go Generics

In Go 1.18, generics provide powerful ways to manipulate types dynamically. One common task is to create new objects of a specified type. Consider the following example:

type FruitFactory[T any] struct{}

func (f FruitFactory[T]) Create() *T {
    // How to create a 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"
}

The FruitFactory attempts to create a new instance of a generic type T. However, returning nil crashes the program. Let's explore how to create new objects in this scenario:

Creating Non-Pointer Objects

If the type T is not a pointer type, you can create a variable and return its address:

func (f FruitFactory[T]) Create() *T {
    var a T
    return &a
}

Alternatively, you can use new(T):

func (f FruitFactory[T]) Create() *T {
    return new(T)
}

Creating Pointer Objects

Creating pointer objects requires more work. You can use type inference to declare a non-pointer variable and convert it to a pointer:

// 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 main() {
    // Instantiating with pointer type
    appleFactory := FruitFactory[*Apple, Apple]{}
    apple := appleFactory.Create()

    // All good
    apple.color = "red"

    fmt.Println(apple) // &{red}
}

The above is the detailed content of How Can I Safely Create Typed Objects of a Generic Type in Go Using Generics?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn