我正在尝试使用 Go 泛型编写一个函数来减少代码中的一些样板 if/else 块。我想出了一些适用于单个类型参数的方法,如下所示:
func valueOrNil[T *int](value T) any {
if value == nil {
return nil
}
return *value
}
Run Code Online (Sandbox Code Playgroud)
虽然这工作正常,但它并不是真正有用,因为它只允许*int, 并且我希望此代码可以与任何原始类型一起使用。我尝试扩展它以支持第二种类型,如下所示:
func valueOrNil[T *int | *uint](value T) any {
if value == nil {
return nil
}
return *value
}
Run Code Online (Sandbox Code Playgroud)
但是,此变体失败并出现编译器错误:
invalid operation: pointers of value (variable of type T constrained by *int|*uint) must have identical base types
Run Code Online (Sandbox Code Playgroud)
谁能发现我在这里做错了什么,或者这样的事情只是“不支持”?
问题似乎在于您试图通过指向类型的指针而不是类型本身来通用。如果我们将指针移动到参数本身而不是类型参数上,它就可以工作。
解释如下,但这是工作代码:
func valueOrNil[T ~int | ~uint](value *T) T {
if value == nil {
var zero T
return zero
}
return *value
}
Run Code Online (Sandbox Code Playgroud)
所以代替这个(这不起作用):
func valueOrNil[T *int | *uint](value T) any
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
func valueOrNil[T int | uint](value *T) any
Run Code Online (Sandbox Code Playgroud)
但是,您可能想更进一步并处理底层类型:
func valueOrNil[T ~int | ~uint](value *T) any
Run Code Online (Sandbox Code Playgroud)
这将允许自定义类型与函数一起使用:
type Thing int
var thing Thing
println(valueOrNil(thing))
Run Code Online (Sandbox Code Playgroud)
您可能需要考虑的另一个方面是返回类型也是通用的。您可以使用相同的T参数来执行此操作。
例如:
func valueOrNil([T ~int | ~uint](value *T) T
Run Code Online (Sandbox Code Playgroud)
但这意味着您需要更改部分实现。而不是这个:
if value == nil {
return nil
}
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
if value == nil {
var zero T
return zero
}
Run Code Online (Sandbox Code Playgroud)