英文:
Instantiate generic interface with any, struct doesn't implement it
问题
有人能解释一下为什么*DataTo
不能满足ToType[any]
吗?
我试图构建一个DTOer
,它将一个结构体的所有值复制到另一个结构体,并设置一些显式的值(在这个例子中是V
)。
以下是代码链接:https://go.dev/play/p/-oobZrw5Ewe
package main
import "fmt"
type DataFrom struct {
V1 int
}
type DataTo struct {
V int
}
func (m *DataTo) SetVal() {
m.V = 1
return
}
type ToType[T any] interface {
SetVal()
*T
}
type DTO[TFrom any, TTo ToType[any]] struct {
Get func(from TFrom) TTo
}
func main() {
dto := &DTO[DataFrom, *DataTo]{
Get: func(from DataFrom) *DataTo {
return &DataTo{V: from.V1 + 666}
},
}
vFrom := DataFrom{V1: 1}
vTo := dto.Get(vFrom)
fmt.Println(vTo.V)
}
英文:
Can someone explain, why *DataTo
does not satisfy ToType[any]
?
Trying to build a DTOer
, that copies all values of one struct to another and also sets some explicit values (V
in this case)
https://go.dev/play/p/-oobZrw5Ewe
// You can edit this code!
// Click here and start typing.
package main
import "fmt"
type DataFrom struct {
V1 int
}
type DataTo struct {
V int
}
func (m *DataTo) SetVal() {
m.V = 1
return
}
type ToType[T any] interface {
SetVal()
*T
}
type DTO[TFrom any, TTo ToType[any]] struct {
Get func(from TFrom) TTo
}
func main() {
dto := &DTO[DataFrom, *DataTo]{
Get: func(from DataFrom) *DataTo {
return &DataTo{V: from.V1 + 666}
},
}
vFrom := DataFrom{V1: 1}
vTo := dto.Get(vFrom)
fmt.Println(vTo.V)
}
答案1
得分: 2
因为any
是一个静态类型。
如果你用它来实例化一个泛型类型,比如ToType
,那个泛型类型将会期望精确的any
。
现在,某些类型参数的用法可能会隐藏这个问题,例如:
type Foo[T any] struct {
Value T
}
Foo[any]{Value: 12} // ok
通常情况下,你可以像上面那样给any
赋予任何类型,因为any
只是空接口interface{}
的别名,任何类型都满足空接口。
当类型参数在*T
等复合类型中使用时,用any
实例化意味着精确地是*any
。因此,你可以将ToType[any]
想象成与以下内容相同:
type ToTypeAny interface {
SetVal()
*any
}
然后*DataTo
显然不是*any
。更多细节请参考:https://stackoverflow.com/questions/68725213/assign-struct-pointer-to-interface-pointer
如果你将结构体声明如下,它将会编译通过:
type DTO[TFrom any, TTo ToType[DataTo]] struct {
Get func(from TFrom) TTo
}
或者以一种更"通用"但也更冗长的方式:
type DTO[TFrom any, T any, TTo ToType[T]] struct {
Get func(from TFrom) TTo
}
&DTO[DataFrom, DataTo, *DataTo]{ ... }
英文:
Because any
is a static type.
If you use it to instantiate a generic type like ToType
, that generic type will expect exactly any
.
Now, certain usages of the type parameter might hide this issue, for example:
type Foo[T any] struct {
Value T
}
Foo[any]{Value: 12} // ok
Normally you are able to assign whatever type to any
like the above, because any
is just an alias of the empty interface interface{}
, and any type satisfies the empty interface.
When the type parameter is used in composite types such as *T
, then instantiating with any
means exactly *any
. Therefore you can imagine ToType[any]
as the same thing as:
type ToTypeAny interface {
SetVal()
*any
}
And then *DataTo
is obviously not *any
. Further details: https://stackoverflow.com/questions/68725213/assign-struct-pointer-to-interface-pointer
If you declare the struct as follows it will compile:
type DTO[TFrom any, TTo ToType[DataTo]] struct {
Get func(from TFrom) TTo
}
Or in a more "generic" but also more verbose way:
type DTO[TFrom any, T any, TTo ToType[T]] struct {
Get func(from TFrom) TTo
}
&DTO[DataFrom, DataTo, *DataTo]{ ... }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论