栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

无论接收器类型如何,接口{}上的动态调用方法

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

无论接收器类型如何,接口{}上的动态调用方法

感谢@Jeremy Wall,我相信我能够解决我的问题。基本问题是在上调用动态命名方法

interface{}
。有4种情况。

  1. interface{}
    基础数据是价值,接收者是价值
  2. interface{}
    基础数据是指针,接收者是值
  3. interface{}
    基础数据是值,接收者是指针
  4. interface{}
    基础数据是指针,接收者是指针

使用反射,我们可以确定接口的基础值。然后,使用进一步的反射,我们可以生成当前数据类型的替代数据类型。如果传入的数据是一个值,我们需要生成一个指向它的指针

value := reflect.ValueOf(data)if value.Type().Kind() == reflect.Ptr {    ptr = value    value = ptr.Elem() // acquire value referenced by pointer} else {    ptr = reflect.New(reflect.TypeOf(i)) // create new pointer    temp := ptr.Elem() // create variable to value of pointer    temp.Set(value) // set value of variable to our passed in value}

现在我们有了两种数据类型,我们可以简单地使用每种数据类型来检查现有方法

var finalMethod reflect.Valuemethod := value.MethodByName(methodName)if method.IsValid() {    finalMethod = method}// check for method on pointermethod = ptr.MethodByName(methodName)if method.IsValid() {    finalMethod = method}if (finalMethod.IsValid()) {    return finalMethod.Call([]reflect.Value{})[0].String()}

因此,考虑到这一点,我们可以有效地动态调用任何方法,无论是声明为

*receiver
还是
receiver

完整的概念证明:http://play.golang.org/p/AU-
Km5VjZs

package mainimport (    "fmt"    "reflect")type Test struct {    Start string}// value receiverfunc (t Test) Finish() string {    return t.Start + "finish"}// pointer receiverfunc (t *Test) Another() string {    return t.Start + "another"}func CallMethod(i interface{}, methodName string) interface{} {    var ptr reflect.Value    var value reflect.Value    var finalMethod reflect.Value    value = reflect.ValueOf(i)    // if we start with a pointer, we need to get value pointed to    // if we start with a value, we need to get a pointer to that value    if value.Type().Kind() == reflect.Ptr {        ptr = value        value = ptr.Elem()    } else {        ptr = reflect.New(reflect.TypeOf(i))        temp := ptr.Elem()        temp.Set(value)    }    // check for method on value    method := value.MethodByName(methodName)    if method.IsValid() {        finalMethod = method    }    // check for method on pointer    method = ptr.MethodByName(methodName)    if method.IsValid() {        finalMethod = method    }    if (finalMethod.IsValid()) {        return finalMethod.Call([]reflect.Value{})[0].Interface()    }    // return or panic, method not found of either type    return ""}func main() {    i := Test{Start: "start"}    j := Test{Start: "start2"}    fmt.Println(CallMethod(i, "Finish"))    fmt.Println(CallMethod(&i, "Finish"))    fmt.Println(CallMethod(i, "Another"))    fmt.Println(CallMethod(&i, "Another"))    fmt.Println(CallMethod(j, "Finish"))    fmt.Println(CallMethod(&j, "Finish"))    fmt.Println(CallMethod(j, "Another"))    fmt.Println(CallMethod(&j, "Another"))}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/471130.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号