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