以下代码会导致错误“无效的复合文字类型 T”。
package main
import "fmt"
func main() {
fmt.Println(createThing[foo]())
}
type thing interface {
foo | bar
}
type foo struct {
id int
a string
}
type bar struct {
id int
b int
}
func createThing[T thing, P *T]() P {
return &T{}
}
如果我只包含foo
在界面thing
,或删除 a string
和b int
所以foo
和bar
完全相同,代码运行不会出错。然而,这是否违背了泛型的目的?为什么我不能实例化这样的泛型类型,尤其是当我什至没有访问任何字段时?
最佳答案
大多数泛型类型对于复合文字来说不是有效类型。但这不是问题,因为还有其他方法可以创建泛型类型的值。
创建指向新零值的指针:
func createThing[T thing]() *T {
return new(T)
}
或者创建一个非指针零值:
func createThing[T thing]() T {
var value T
return value
}
至于为什么以这种方式发生错误,这里是规范中的解释,经过修改以解决您的具体问题。
The LiteralType's core type T must be a struct, array, slice, or map type
core type是什么? ?
An interface T has a core type if [...] there is a single type U which is the underlying type of all types in the type set of T
No other interfaces have a core type.
underlying type是什么? ?
Each type T has an underlying type: If T is one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type is T itself. Otherwise, T's underlying type is the underlying type of the type to which T refers in its declaration.
“类型文字”可以指文字结构类型,例如 struct{int id}
。所以,当 foo
和bar
两者的底层类型均为 struct{int id}
,然后thing
核心类型为 struct{int id}
,因此复合文字是可能的。当foo
和bar
没有相同的基础类型,则 thing
没有核心类型,并且复合文字是不可能的,因此你的错误。
正式的定义可能看起来很复杂,但结果和实际要点很简单:泛型代码只能表达可能类型的常见行为。除了在所有基础类型都相同的特殊情况下,文字值并不是常见的行为。
关于Go 泛型 : Invalid composite literal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75045168/