你如何编写一个允许指向多个原始类型的指针的通用 Go 函数?

How do you write a generic Go function that allows pointers to multiple primitive types?

我正在尝试使用 Go 泛型编写一个函数来减少我们代码中的一些样板 if/else 块。我想出了 something that works for a single type parameter 如下:

func valueOrNil[T *int](value T) any {
    if value == nil {
        return nil
    }
    return *value
}

虽然这工作正常,但它并不是很有用,因为它只允许 *int,而且我希望这段代码适用于任何原始类型。我试图扩展它以支持第二种类型,as follows:

func valueOrNil[T *int | *uint](value T) any {
    if value == nil {
        return nil
    }
    return *value
}

但是,此变体因编译器错误而失败:

invalid operation: pointers of value (variable of type T constrained by *int|*uint) must have identical base types

任何人都可以发现我在这里做错了什么,或者像这样的东西只是“不受支持”吗?

问题似乎在于您试图通过 指向类型的指针 而不是 类型本身 来实现通用。如果我们将指针移动到参数本身而不是类型参数上,它就可以工作。

解释如下,但这里是工作代码:

func valueOrNil[T ~int | ~uint](value *T) T {
    if value == nil {
        var zero T
        return zero
    }
    return *value
}

所以不是这个(这是行不通的):

func valueOrNil[T *int | *uint](value T) any

你可以这样做:

func valueOrNil[T int | uint](value *T) any

但是,您可能希望更进一步并处理基础类型:

func valueOrNil[T ~int | ~uint](value *T) any

这将允许自定义类型与函数一起使用:

type Thing int

var thing Thing
println(valueOrNil(thing))

您可能要考虑的另一个方面是 return 类型的通用性。您可以使用相同的 T 参数。

例如:

func valueOrNil([T ~int | ~uint](value *T) T

但这意味着您需要更改部分实现。而不是这个:

if value == nil {
    return nil
}

你可以这样做:

if value == nil {
    var zero T
    return zero
}

from Miquella (thanks for the insights; I learned something about the usage of ~, too) made me realize that I don't actually need to specify a specific type once I move the * onto the parameter type, so this is what I ended up with:

func valueOrNil[T any](value *T) any {
    if value == nil {
        return nil
    }
    return *value
}