这可以:
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)
为什么包含不属于同一“类型组”的类型的约束会导致此错误,我应该如何处理它?
这个语法:
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{}作为字段类型。如需一些灵感,请参阅此处或此处。