将值文字分配给泛型类型的结构字段,而不会遇到 IncompleteAssign 错误

Bel*_*dev 3 generics go

这可以:

type constraint interface {
    ~float32 | ~float64
}

type foo[T constraint] struct {
    val T
}

func (f *foo[float64]) setValToPi() {
    f.val = 3.14
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我更改constraint为还包含int类型,则会遇到错误:

type constraint interface {
    ~float32 | ~float64 | ~int
}

type foo[T constraint] struct {
    val T
}

func (f *foo[float64]) setValToPi() {
    f.val = 3.14 // IncompatibleAssign: cannot use 3.14 (untyped float constant) as float64 value in assignment
}
Run Code Online (Sandbox Code Playgroud)

为什么包含不属于同一“类型组”的类型的约束会导致此错误,我应该如何处理它?

bla*_*een 5

这个语法:

func (f *foo[float64]) setValToPi() {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

只是一个方法声明。它不会实例化泛型类型foo。方括号内的标识符float64是类型参数的名称。它可能是T正如类型定义中那样,也

就像你写的:

type foo[float64 constraint] struct {
    val float64
}
Run Code Online (Sandbox Code Playgroud)

自从float64是一个预先声明的标识符,因此您可以使用类型参数名称来隐藏它。

因此,在该方法中setValToPi,关于 的类型的唯一已知信息val是它被限制为constraint,例如 的并集。~float32 | ~float64 | ~int

如果将方法声明更改为:

func (f *foo[T]) setValToPi() {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

相反,您将得到相同的错误T

不能使用 3.14(无类型浮点常量)作为赋值中的 T 值

错误是由以下事实给出的3.14:(无类型浮点常量)不能总是分配给 的所有可能实例,特别是确实是的foo[T]实例T~int

带有float64标识符作为类型参数的 Playground:https ://gotipplay.golang.org/p/1EuAsSKdihK

解决方案是让该方法接受类型参数类型的值(除了使用不太容易混淆的标识符之外):

func (f *foo[T]) SetValue(val T) {
    f.val = val
}
Run Code Online (Sandbox Code Playgroud)

这当然意味着您不能设置像 那样的固定值3.14,但正如所解释的,这首先是一个错误。其他可能的解决方案是使用any/interface{}作为字段类型。如需一些灵感,请参阅此处此处