为什么 Go 不允许将一个泛型分配给另一个泛型?
Why does Go not allow assigning one generic to another?
以下代码会引发编译错误
cannot use ExampleProps (variable of type Props[Example]) as Props[Generic] value in return statement
// Abstract
type Generic interface {
ID() string
}
type Props[G Generic] struct{}
// Example
type Example struct {
id string
}
func (example Example) ID() string {
return example.id
}
var ExampleProps = Props[Example]{}
// Problem
func Problem() Props[Generic] {
return ExampleProps
}
我的问题是:由于 Example
实现了 Generic
,为什么 Go 不允许将 Props[Example]
分配给 Props[Generic]
?
实例化具有不同类型参数的泛型类型会产生两个新的不同命名类型。
请注意,每次提供类型参数(包括函数参数或 return 类型)时,您都在实例化通用类型:
// Props is instantiated with type argument 'Generic'
func Problem() Props[Generic] {
return ExampleProps
}
因此 Props[Example]
与 Props[Generic]
的类型不同,您不能在需要另一种类型的地方使用一种类型的值。用作参数的类型本身是否满足可分配性的某些条件并不重要,例如接口和实现者。 用 any
实例化的泛型也是如此。 any
类型只是另一种静态类型——interface{}
的别名。它不等于 T
也不等于“任何类型”。
简单来说,就好像您在使用 int
,而应该是 string
。
你可以做的修复它并保持一些灵活性是用类型参数实例化 Props
——这是否有意义取决于你实际计划如何使用这个函数。总之,作为示范:
// adding a field to make this a bit less contrived
type Props[G Generic] struct{ Value G }
// Props instantiated with T, adequately constrained
func Problem[T Generic](v T) Props[T] {
return Props[T]{ Value: v }
}
func main() {
a := Problem(Example{})
fmt.Println(a)
}
以下代码会引发编译错误
cannot use ExampleProps (variable of type Props[Example]) as Props[Generic] value in return statement
// Abstract
type Generic interface {
ID() string
}
type Props[G Generic] struct{}
// Example
type Example struct {
id string
}
func (example Example) ID() string {
return example.id
}
var ExampleProps = Props[Example]{}
// Problem
func Problem() Props[Generic] {
return ExampleProps
}
我的问题是:由于 Example
实现了 Generic
,为什么 Go 不允许将 Props[Example]
分配给 Props[Generic]
?
实例化具有不同类型参数的泛型类型会产生两个新的不同命名类型。
请注意,每次提供类型参数(包括函数参数或 return 类型)时,您都在实例化通用类型:
// Props is instantiated with type argument 'Generic'
func Problem() Props[Generic] {
return ExampleProps
}
因此 Props[Example]
与 Props[Generic]
的类型不同,您不能在需要另一种类型的地方使用一种类型的值。用作参数的类型本身是否满足可分配性的某些条件并不重要,例如接口和实现者。 用 any
实例化的泛型也是如此。 any
类型只是另一种静态类型——interface{}
的别名。它不等于 T
也不等于“任何类型”。
简单来说,就好像您在使用 int
,而应该是 string
。
你可以做的修复它并保持一些灵活性是用类型参数实例化 Props
——这是否有意义取决于你实际计划如何使用这个函数。总之,作为示范:
// adding a field to make this a bit less contrived
type Props[G Generic] struct{ Value G }
// Props instantiated with T, adequately constrained
func Problem[T Generic](v T) Props[T] {
return Props[T]{ Value: v }
}
func main() {
a := Problem(Example{})
fmt.Println(a)
}