[英]How to get the pointer to a struct passed through interface{} in golang?
No, I don't think this is a duplicate of How to determine an interface{} value's "real" type?
不,我不认为这与如何确定interface {}值的“真实”类型重复吗? .
。 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{}
. 最近,我遇到了
interface{}
麻烦。 I have a variable with type A been passed through interface{}
, a method Tt
is defined with *A as the receiver. 我有一个类型A的变量通过
interface{}
传递,方法Tt
定义为* A作为接收者。
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. 我想调用方法
Tt
但失败了,因为该变量在interface{}
并且我无法获得指向该变量的指针。
As you can see, reflect.TypeOf(v)
gives the correct type A
, but reflect.TypeOf(&v)
gives *interface {}
instead of *A
. 如您所见,
reflect.TypeOf(v)
给出正确的类型A
,但是reflect.TypeOf(&v)
给出*interface {}
而不是*A
Is there any way to get *A
? 有什么办法可以得到
*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
传入
T
的interface
,然后可以得到*T
的interface
To call the pointer method Tt()
, you must have an *A
(or take the address of an addressable A
value). 要调用指针方法
Tt()
,您必须具有*A
(或采用可寻址 A
值的地址)。 The A
value in variable b
is not addressable , and therefore the A
pointer methods are not accessible through b
. 变量
b
的A
值不可寻址 ,因此无法通过b
访问A
指针方法。
The fix is to start with the address of a
: 解决方法是从
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. 在呼叫
reflect.ValueOf(v)
在值v
被作为参数传递。 The ValueOf
function unpacks the empty interface to recover a value of type A
. ValueOf
函数将空接口ValueOf
以恢复类型A
的值。
In the call reflect.ValueOf(&v)
, an *interface{}
is stored in the empty interface, which is then passed as the argument. 在调用
reflect.ValueOf(&v)
, *interface{}
存储在空接口中,然后将其作为参数传递。 The ValueOf
function unpacks the empty interface to recover a value of type *interface{}
. ValueOf
函数将空接口ValueOf
以恢复*interface{}
类型的值。 This is the address of the variable v
, not the address of the variable a
. 这是变量
v
的地址,而不是变量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
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.