为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
斯蒂芬大帝 2022-11-23 20:13:03

我正在尝试使用 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

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


查看完整描述

2 回答

?
隔江千里

TA贡献1608条经验 获得超10个赞

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


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


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))

您可能要考虑的另一个方面是对返回类型也进行泛化。您可以使用相同的T参数来执行此操作。


例如:


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

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


if value == nil {

    return nil

}

你可以这样做:


if value == nil {

    var zero T

    return zero

}


查看完整回答
反对 回复 2022-11-23
?
www说

TA贡献1500条经验 获得超8个赞

我从Miquella那里接受的答案(感谢您的见解;我也了解了 的用法)让我意识到,一旦我将 the移到参数类型上,我实际上并不需要指定特定类型,所以这就是我结束了~*

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

    if value == nil {

        return nil

    }

    return *value

}




查看完整回答
反对 回复 2022-11-23

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信