从受限于接口的通用函数返回 nil?

问题描述 投票:0回答:1

我即将迁移现有代码以使用 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
不允许这样做?

谁能告诉我更多关于行为或背后的理性?

提前谢谢你!

go generics
1个回答
1
投票

类型参数不是它的约束。

  1. 约束仅限制可用于实例化该类型参数的具体类型,并可能确定该类型参数支持哪些操作
  2. 类型参数仅在编译时存在。在运行时,代码使用提供给函数的任何具体类型参数进行操作。
  3. 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
}
© www.soinside.com 2019 - 2024. All rights reserved.