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)
}
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: 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]{ ... }