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

我可以为通用函数创建别名吗?我收到错误“无法在没有实例化的情况下使用通用函数”

我可以为通用函数创建别名吗?我收到错误“无法在没有实例化的情况下使用通用函数”

Go
慕雪6442864 2022-11-23 16:00:05

我可以定义一个通用函数:


package hello


func IsZero[T int64|float64](value T) bool {

   return value == 0

}

然后,如果我尝试在另一个包中为该函数起别名,它将失败:


package world


import "hello"


var IsZero = hello.IsZero

以上不编译:


没有实例化就不能使用通用函数 hello.IsZero


相反,这有效:


var IsZero = hello.IsZero[int64]

是否可以使用其他语法来做到这一点?


查看完整描述

3 回答

?
呼啦一阵风

TA贡献1527条经验 获得超5个赞

那不是别名。实际上,您已经有了答案。但是如果你想要一个正式的参考,从语言规范,Instantiations:


未调用的泛型函数需要类型参数列表进行实例化


因此,当您尝试初始化函数类型的变量时,hello.IsZero不会调用该函数,因此需要使用特定类型参数进行实例化:


// not called, instantiated with int64

var IsZero = hello.IsZero[int64]

此时变量(为了清楚起见,我们给它起一个不同的名字)zeroFunc有一个具体的函数类型:


    var zeroFunc = IsZero[int64]

    fmt.Printf("type: %T\n", zeroFunc) 

印刷:


type: func(int64) bool

这可能是也可能不是您想要的,因为这有效地单态化了函数。


如果您只想拥有一个具有相同实现(或其调整版本)的本地符号,则可以声明一个“包装器”函数。请记住,您的包装器的类型参数只能与包装器的类型参数一样严格或更严格


例如给定


IsZero[T int64 | float64](v T)

你的包装纸不能


WrapIsZeroPermissive[T int64 | float64 | complex128](v T) bool {

    return IsZero(v) // does not compile, T's type set is a superset

}

但可以_


WrapIsZeroStricter[T int64](v T) bool {

    return IsZero(v) // ok, T's type set is a subset

}


查看完整回答
反对 回复 2022-11-23
?
慕田峪9158850

TA贡献1513条经验 获得超7个赞

如果功能很小,就像在问题中一样,那么将它卖掉可能会更容易:


package vendor


func thisIsJustCopy[T int64|float64](value T) bool {

   return value == 0

}

但如果功能很大,你可以这样做:


package world

import "hello"


func IsZero[T int64|float64](value T) bool {

   return hello.IsZero(value)

}


查看完整回答
反对 回复 2022-11-23
?
慕哥6287543

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

我尝试在另一个包中为该函数起别名

别名仅适用于类型。您的代码只是试图声明一个变量。

是否可以使用其他语法来做到这一点?

不。


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

添加回答

举报

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