Suppose that I have the following types, the following snippets mimic production code:
import (
"reflect"
)
type IFace interface {
A()
B()
C()
}
type Meta struct {
s string
}
func (m *Meta) A() {}
func (m *Meta) B() {}
func (m *Meta) C() {}
type One struct {
M *Meta
B bool
}
func (o *One) A() {}
func (o *One) B() {}
func (o *One) C() {}
And I have a method that does the following:
func Alias(src, dest *Meta) (IFace, error) {
base, err := find(src) //asume that `find` is implemented and err is nil
if err != nil {
return err
}
// trouble starts here ...
// allocate new "instance"
aliased := reflect.New(reflect.TypeOf(base)).Elem().Interface()
// copy the base value
aliased = base
aliasedV := reflect.ValueOf(aliased).Elem()
fm := aliasedV.FieldByName("M")
fm.Set(reflect.ValueOf(dest))
return aliasedV.Interface().(Iface), nil
}
It compiles and runs however with the following TestFunction it gives me this error message:
interface conversion: One is not IFace: missing method C [recovered]
panic: interface conversion: One is not IFace: missing method C
and the test function:
func TestOne(t *testing.T) {
srcID := &Meta{S: "SRC"}
destID := &Meta{S: "DEST"}
aliased, err := Alias(srcID, destID)
if err != nil {
t.Error(err)
}
one, isOne := aliased.(*One)
if !isOne {
t.Error("fail")
}
}
Is there a way to have an interface{}
type that wraps a struct value become an interface{}
type that wraps a struct pointer without using the underlying struct type directly, like avoiding: var any interface{} = aliased.(*One)
??,
Could the unsafe
package be of help here?
Aucun commentaire:
Enregistrer un commentaire