首页 >后端开发 >Golang >如何在 Go 1.18 泛型中创建类型化值的非 Nil 对象?

如何在 Go 1.18 泛型中创建类型化值的非 Nil 对象?

Patricia Arquette
Patricia Arquette原创
2024-12-10 08:11:12144浏览

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