No, I don't think this is a duplicate of How to determine an interface{} value's "real" type? . I know how to get the Type of an interface variable, but I can't find a way to get the pointer to an interface{}'s real type.
Recently, I got into trouble with interface{}
. I have a variable with type A been passed through interface{}
, a method Tt
is defined with *A as the receiver.
I want to call the method Tt
but failed because the variable is in an interface{}
and I can't get the pointer to the variable.
As you can see, reflect.TypeOf(v)
gives the correct type A
, but reflect.TypeOf(&v)
gives *interface {}
instead of *A
.
Is there any way to get *A
?
package main
import (
"fmt"
"reflect"
)
type SomeStruct1 struct{
}
type SomeStruct2 struct{
}
type SomeStruct3 struct{
}
etc...
func (*SomeStruct1) SomeMethod(){
fmt.Println("hello")
}
func (*SomeStruct2) SomeMethod(){
fmt.Println("hello")
}
func (*SomeStruct3) SomeMethod(){
fmt.Println("hello")
}
etc...
func DoSomething(arg interface{}){
switch v:=b.(type){
[]byte:{
dosomething for []byte
}
default:{
var m reflect.Value
if value.Kind() != reflect.Ptr {
m = reflect.ValueOf(&v).MethodByName("SomeMethod")
} else {
m = reflect.ValueOf(v).MethodByName("SomeMethod")
}
m.Call(nil)
}
}
func main() {
DoSomething([]byte{...})
DoSomething(SomeStruct1{})
DoSomething(&SomeStruct1{})
etc..
}
Use reflection:
//
// Return a pointer to the supplied struct via interface{}
//
func to_struct_ptr(obj interface{}) interface{} {
vp := reflect.New(reflect.TypeOf(obj))
vp.Elem().Set(reflect.ValueOf(obj))
return vp.Interface()
}
Pass in an interface
with T
, then you can get an interface
with *T
To call the pointer method Tt()
, you must have an *A
(or take the address of an addressable A
value). The A
value in variable b
is not addressable , and therefore the A
pointer methods are not accessible through b
.
The fix is to start with the address of a
:
var a A
var b interface{}
b = &a // Note change on this line
switch v := b.(type) {
default:
reflect.ValueOf(v).MethodByName("Tt").Call(nil)
}
In the call reflect.ValueOf(v)
, the value in v
is passed as the argument. The ValueOf
function unpacks the empty interface to recover a value of type A
.
In the call reflect.ValueOf(&v)
, an *interface{}
is stored in the empty interface, which is then passed as the argument. The ValueOf
function unpacks the empty interface to recover a value of type *interface{}
. This is the address of the variable v
, not the address of the variable a
.
Reflection is not required in this specific example:
var a A
var b interface{}
b = &a
switch v := b.(type) {
case interface {
Tt()
}:
v.Tt()
default:
fmt.Println("not handled")
}
You need just type cast. Example:
type SomeStruct1 struct{
someList []string
}
func (s *SomeStruct1) print() {
fmt.Printf("%v\n", s.someList)
...
func Call(T interface{}){
switch T.(type){
case *SomeStruct1:
t := T.(*SomeStruct1) // cast as pointer to struct
t.print()
...
}
}
func main() {
a := SomeStruct{
someList: []string{"a", "b"}
}
Call(&a) // pass a as ptr
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.