Home >Backend Development >Golang >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!