我即将迁移现有代码以使用 go generics。这个非常基本的例子说明了问题:
// Just an interface
type Object interface {
Test() error
}
// A func returning an interface can return `nil`
func Get() Object {
return nil
}
// Why I can't return `nil` from a generic func constrained to `interface Object`?
func GetG[T Object]() T {
return nil // ./prog.go:15:9: cannot use nil as T value in return statement
}
https://go.dev/play/p/3WTg1aYDzCA
如果允许返回
func Get
的interface Object
返回nil
,为什么T被限制为func GetG
的通用版本Object
不允许这样做?
谁能告诉我更多关于行为或背后的理性?
提前谢谢你!
类型参数不是它的约束。
nil
可能无法分配给具体类型参数直觉上,假设我使用定义的整数类型实现您的接口:
type Foo int8
func (Foo) Test() error { return nil }
Foo
是否满足约束Object
?是的,它实现了方法。我可以用 GetG
实例化 Foo
吗?是的,它满足约束条件。我可以将nil
分配给Foo
吗? 不,我不能:
为变量分配存储时,[...] 变量或值被赋予默认值。 [...]
用于指针、函数、接口、切片、通道和映射。nil
因此,如果返回类型只是类型参数,则不能返回
nil
。您可以在其他情况下退货nil
,例如如果返回类型是指向类型参数的指针,但那不是T
,它是*T
.
func GetG[T Object]() *T {
return nil // ok
}
这对您的程序可能有意义,也可能没有意义。 否则你可以做的是返回
T
的零值,你可以通过几种不同的方式来做,最直接的一种是:
func GetG[T Object]() T {
var zero T
return zero
}