I've 2 structs, Both embedded another struct called Test
.
The struct Created at Compile time EmbeddedCompiledStruct
is able to access the Method from Test
struct. However the Dynamically created Struct is able to access the Method only if it is accessed via the struct but not via its Pointer.
// Test ...
type Test struct {
Name string
}
// TableName ...
func (Test) TableName() string {
fmt.Printf("MyTableName called")
return "MyTableName"
}
// EmbeddedCompiledStruct ...
type EmbeddedCompiledStruct struct {
Test
}
type tabler interface {
TableName() string
}
func main() {
structFields := []reflect.StructField{
{
Name: "Type",
Type: reflect.TypeOf(Test{}),
Tag: `json:"-" gorm:"-"`,
Anonymous: true,
},
{
Name: "Name",
Type: reflect.TypeOf(""),
Tag: `json:"name,omitempty" gorm:"column:Name;not null;size:16;primary_key"`,
},
}
structDec := reflect.StructOf(structFields)
compiledStruct := reflect.TypeOf(EmbeddedCompiledStruct{})
// Normal Structs
fmt.Printf("\nType Dynamic Embedded Struct Methods : %+v\n", structDec)
for i := 0; i < structDec.NumMethod(); i++ {
fmt.Println(structDec.Method(i).Name)
}
fmt.Printf("\nType Compiled Embedded Struct Methods : %+v\n", compiledStruct)
for i := 0; i < compiledStruct.NumMethod(); i++ {
fmt.Println(compiledStruct.Method(i).Name)
}
// Pointer to Structs
t1 := reflect.TypeOf(reflect.New(structDec).Interface())
fmt.Printf("\nType Dynamic Embedded Struct Pointer Methods : %+v\n", t1)
// -----> Here its missing TableName Method
for i := 0; i < t1.NumMethod(); i++ {
fmt.Println(t1.Method(i).Name)
}
t3 := reflect.TypeOf(reflect.New(compiledStruct).Interface())
fmt.Printf("\nType Compiled Embedded Struct Pointer Methods : %+v\n", t3)
for i := 0; i < t3.NumMethod(); i++ {
fmt.Println(t3.Method(i).Name)
}
fmt.Println("")
if tabler, ok := reflect.New(structDec).Interface().(tabler); ok {
fmt.Println("Convertible Dynamic Struct " + tabler.TableName())
} else {
fmt.Println("Not convertible Dynamic Struct")
}
if tabler, ok := reflect.New(compiledStruct).Interface().(tabler); ok {
fmt.Println("Convertible Compiled Struct " + tabler.TableName())
} else {
fmt.Println("Not convertible Compiled Struct")
}
}
Output:
Type Dynamic Embedded Struct Methods : struct { Type main.Test "json:\"-\" gorm:\"-\""; Name string "json:\"name,omitempty\" gorm:\"column:Name;not null;size:16;primary_key\"" }
TableName
Type Compiled Embedded Struct Methods : main.EmbeddedCompiledStruct
TableName
Type Dynamic Embedded Struct Pointer Methods : *struct { Type main.Test "json:\"-\" gorm:\"-\""; Name string "json:\"name,omitempty\" gorm:\"column:Name;not null;size:16;primary_key\"" }
Type Compiled Embedded Struct Pointer Methods : *main.EmbeddedCompiledStruct
TableName
Not convertible Dynamic Struct
MyTableName calledConvertible Compiled Struct MyTableName
The t1
Object doesn't Print the method name TableName
. However the object created from Compiled Struct works fine in both scenario's even though they embed the same struct.
Why is DynamicStruct Pointer not able to Get the Embedded Methods but a Compiled Struct is able to do it? Is this a bug of some sort in Golang?
Playground : https://play.golang.org/p/zrWP0WfL9lQ
Aucun commentaire:
Enregistrer un commentaire