你正在使用的Go版本是什么( go version
)?
$ go version
go version go1.12.1 darwin/amd64
这个问题在最新的版本中是否会重现?
是的。
你正在使用什么操作系统和处理器架构( go env
)?go env
输出
$ go env
GOARCH="amd64"
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
你做了什么?
我调用了 types.AssignableTo
来检查一个未指定类型的整数常量是否可以分配给一个命名的整数类型。
https://play.golang.org/p/Xq33qWpFsy5
你期望看到什么?
我期望它是可分配的。
但实际上你看到了什么?
它被报告为不可分配。
起初我认为这是由于隐式类型转换,它们在技术上不是可分配的,但在规范中,可分配性似乎包括隐式转换,至少对于非常量值。特别是对于未指定类型的常量,规范说明了一个未指定类型的常量 x 是可分配给类型 T 如果 x is in the set of values determined by T.
。我不确定这具体意味着什么,或者是否会使这种情况不符合条件。总的来说,由于未指定的常量确实是可分配给命名类型的,所以我假设AssignableTo函数会同意。
另外请注意,reflect.Type.AssignableTo的行为与types.AssignableTo一致。
/cc @griesemer,因为你是go/types的主要所有者
5条答案
按热度按时间cngwdvgl1#
经过进一步思考,我怀疑问题出在AssignableTo不知道常量的值。如果它在这个情况下返回
true
,那么由于整数符号不匹配和溢出,将会出现误报。退一步说,我正在尝试让gopls(x/tools LSP实现)在建议未指定类型的常量作为补全候选项时更加智能(即,只有在它可以分配给光标处的预期类型时,才应该建议一个常量)。换句话说,我想确定给定的
*types.Const
是否可以分配给给定的types.Type
。看起来,如果有一种方法可以设置操作数的"val",AssignableTo代码路径将会做正确的事情。63lcw9qa2#
我同意在这种情况下,go/types的行为至少值得更仔细地观察。
p1tboqfb3#
@muirrn的确,AssignableTo在这个情况下不知道未类型化的int值。然而,返回false也不是很令人满意;它可能应该返回一些错误(或恐慌)-但我们不能改变这一点。
除非在API中添加另一个入口点,我不知道还能在这里做些什么,但我将这个问题保留开放(并重新定义标题),作为提醒大家审查代码路径(并更好地记录它)。
kg7wmglp4#
谢谢,听起来合理。
为了其他人的未来参考,为了在假阳性和假阴性之间做出选择,我做了一些类似的事情:https://play.golang.org/p/1G9aEFaLenH
xdnvmnnf5#
@griesemer 可能是相关的,以下内容在我的预期中为假时却打印为真:
这似乎在gopls中引起了一些误报的完成候选项,因为gopls认为一个未类型的浮点常量可以分配给一个整型变量。
编辑:这是使用Go 1.16.2版本的情况。
/cc @findleyr