No, I don't think this is a duplicate of
How to determine an interface{} values"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.
最近,我遇到了
我想调用方法
如您所见,
有什么方法可以获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | 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.. } |
- 使用反射包
- 如何确定interface {}值"真实"类型的可能重复项?
-
为什么不将方法
Tt 放在界面中并完成呢? 不使用任何反射? - 请提供一个合理的例子。 即使打算在这里似乎对我来说也错
-
@Yerken,我已进行编辑以提供更详细的示例。 我希望函数
DoSomething 接受SomeStruct 和*SomeStruct
使用反射:
1 2 3 4 5 6 7 8 | // // 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() } |
用
要调用指针方法
解决方法是从
1 2 3 4 5 6 7 | 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) } |
在调用
在调用
在此特定示例中,不需要反射:
1 2 3 4 5 6 7 8 9 10 11 | var a A var b interface{} b = &a switch v := b.(type) { case interface { Tt() }: v.Tt() default: fmt.Println("not handled") } |
-
是的,那行得通。 但是我确实认为
reflect.ValueOf(v) 给A 而reflect.ValueOf(&v) 给* interface{} 很奇怪 - 我在答案中添加了更多解释。
您只需要键入强制类型转换。
例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | type SomeStruct1 struct{ someList []string } func (s *SomeStruct1) print() { fmt.Printf("%v ", 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 } |