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

我正在尝试使用 Go 泛型来编写一个函数来减少我们代码中的一些样板 if/else 块。我想出了一些适用于单个类型参数的东西,如下所示:


func valueOrNil[T *int](value T) any {

    if value == nil {

        return nil

    }

    return *value

}

虽然这很好用,但它并不是很有用,因为它只允许*int, 并且我希望这段代码适用于任何原始类型。我试图扩展它以支持第二种类型,如下所示:


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

谁能发现我在这里做错了什么,或者只是“不支持”这样的事情?


斯蒂芬大帝
浏览 64回答 2
2回答

隔江千里

问题似乎是您试图通过指向类型的指针而不是类型本身来实现通用。如果我们将指针移动到参数本身而不是类型参数上,它就可以工作。解释如下,但这是工作代码: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 intvar thing Thingprintln(valueOrNil(thing))您可能要考虑的另一个方面是对返回类型也进行泛化。您可以使用相同的T参数来执行此操作。例如:func valueOrNil([T ~int | ~uint](value *T) T但这意味着您需要更改部分实现。而不是这个:if value == nil {    return nil}你可以这样做:if value == nil {    var zero T    return zero}

www说

我从Miquella那里接受的答案(感谢您的见解;我也了解了 的用法)让我意识到,一旦我将 the移到参数类型上,我实际上并不需要指定特定类型,所以这就是我结束了:~*func valueOrNil[T any](value *T) any {    if value == nil {        return nil    }    return *value}
打开App,查看更多内容
随时随地看视频慕课网APP