你正在使用哪个版本的Go(go version
)?
$ go version
go version go1.20.3 linux/amd64
这个问题在最新版本中是否会重现?
是的
你做了什么?
package main
type I interface {
M(int)
P()
}
type V int
func (v V) P() { println(v) }
func (v *V) M(n int) { *v = V(n) }
type S struct{ *V }
func F[T I](x T) {
defer x.P()
x.M(9)
}
func G(x *S) {
defer x.P()
x.M(9)
}
func main() {
{
var s = S{V: new(V)}
F(&s) // 9
}
{
var s = S{V: new(V)}
G(&s) // 0
}
}
你的预期结果是什么?
相同的行为。
你实际看到的结果是什么?
不同的行为。
6条答案
按热度按时间ldfqzlk81#
这不是泛型与非泛型的比较,而是具体类型与接口类型的比较。将
F
改为接口类型后,它还会打印9
:据我所知,这种行为是正确的。根据规范:
对于类型为 I 的值 x,其中 I 是接口类型,x.f 表示 x 的动态值的实际方法 f。
qcbq4gxm2#
但是
&s
不是一个接口,这就是问题所在。vom3gejh3#
可能与 #52025 有关。
CC @randall77@mdempsky
km0tfn4u4#
我认为这应该是一个新的问题,而不是一个积压问题。
kmpatx3s5#
正如@cuonglm所指出的,使用类型参数的通用代码的行为与接口调用的工作方式相同。我同意这一点,这与将相同的代码专门用于执行单个具体类型参数时的工作方式不同。
我认为这是一个规范歧义问题。在我看来,提升方法、接口方法调用、方法值和延迟语句的语义仍然模糊不清。
cczfrluj6#
看起来这个特定问题更多地是关于接口方法值和非接口方法值评估之间的不一致性:
这确实打破了许多人将类型参数始终视为接口的预期。