教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 golang反射——执行函数

golang反射——执行函数

发布时间:2021-12-03   编辑:jiaochengji.com
教程集为您提供golang反射——执行函数等资源,欢迎您收藏本站,我们将为您提供最新的golang反射——执行函数资源

  在写golang框架的时候,免不了需要处理类似方法执行的问题,由于框架层对业务层的具体方法是不清楚了,只提供了基本的输入和输出格式,所以就需要使用一种方式,适配业务层的函数调用。

golang提供了反射,其中最终要的两个内容是Type和Value。通过反射,我们可以new一个struct,或者实现赋值等操作。可以简单理解为使用另一种方式实现对程序的处理。说了这么多,本篇文章着重介绍如何使用golang的反射机制,实现对函数的调用。

主要参考

https://studygolang.com/articles/12348?fr=sidebar

https://jimmyfrasche.github.io/go-reflection-codex/#invoke-a-function

好,下面上货。

<pre class="has"><code class="language-Go">package demo import ( "errors" "fmt" "reflect" "testing" ) func hello() { fmt.Println("123") } func xixi(a int) (string, error) { fmt.Println(a) return "abc", nil } func haha(p ...int) (string, error) { fmt.Println(p) return "haha", errors.New("bad bad...") } type msg struct { name string } type specialMsg struct { msg age int } func lala(p ...int) (*msg, error) { fmt.Println(p) return &msg{ name: "lalalaa", }, nil } func xaxa(a *msg) (string, error) { fmt.Println(a.name) return "ok", nil } func xaxa2(b *specialMsg) (string, error) { fmt.Println(b.name) return "lllala", nil } //反射调用 func invoke(f interface{}, params ...interface{}) []reflect.Value { fv := reflect.ValueOf(f) realParams := make([]reflect.Value, len(params)) //参数 for i, item := range params { realParams[i] = reflect.ValueOf(item) } rs := fv.Call(realParams) return rs } func TestNewStudent(t *testing.T) { //无参数调用 k := invoke(hello) fmt.Println(k) //固定参数调用 c := invoke(xixi, 12) fmt.Println(c) //可变参数调用 j := invoke(haha) fmt.Println(j) //如何处理返回值 fmt.Printf(j[0].String()) fmt.Printf(j[0].Kind().String()) err := j[1].Interface().(error) if err != nil { fmt.Printf(err.Error()) } m := invoke(lala, 1, 2, 3) fmt.Println(m[0].Pointer()) fmt.Println(m[0].Kind().String()) //返回结构体指针(进行强制转换) rrr := m[0].Interface().(*msg) fmt.Println(rrr) fmt.Println(rrr.name) fmt.Println(m) tempP := &msg{ name: "sdfdfdf", } ss := invoke(xaxa, tempP) fmt.Println(ss) tempSpecalMsg := &specialMsg{ msg: msg{ name: "aaaa", }, age: 0, } ss2 := invoke(xaxa2, tempSpecalMsg) fmt.Println(ss2) } </code></pre>

 

简单说实现了对各种函数的一个反射调用。注意,这里是函数,不是方法,方法的话有些区别,可以参考上面的几个连接。

最后说一下需要注意的。

首先是这里的error,我们定义函数的返回值如果是error,那么需要注意从Value转换到error,没有直接转换的方法,需要先得到interface{}然后在转换为error才可以。同理对于自定义的参数,比如结构体,也需要先转换为interface{},然后在转换为结构体才可以。

运行结果:

<pre class="has"><code>GOROOT=/usr/local/go1.12.5 #gosetup GOPATH=/Users/wuxueyou/gopath #gosetup /usr/local/go1.12.5/bin/go test -c -o /private/var/folders/6q/swpkld2x38q9cqpkq75l18_80000gn/T/___TestNewStudent_in_study004_demo study004/demo #gosetup /usr/local/go1.12.5/bin/go tool test2json -t /private/var/folders/6q/swpkld2x38q9cqpkq75l18_80000gn/T/___TestNewStudent_in_study004_demo -test.v -test.run ^TestNewStudent$ #gosetup === RUN TestNewStudent 123 [] 12 [abc <error Value>] [] [haha <error Value>] hahastringbad bad...[1 2 3] 824633982992 ptr &{lalalaa} lalalaa [<*demo.msg Value> <error Value>] sdfdfdf [ok <error Value>] aaaa [lllala <error Value>] --- PASS: TestNewStudent (0.00s) PASS Process finished with exit code 0</code></pre>

 

到此这篇关于“golang反射——执行函数”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
php实现简单用户登录功能程序代码
asp.net常用http状态码表
Java反射(泛型擦除演示)的例子
PHP无限级分类菜单实例程序
golang反射——执行函数
MySQL中group_concat函数使用例子
更改MySQL数据库名实例代码
php5 字符串处理函数汇总
mysql中thread_cache和table_cache参数详解
使用SHOW PROFILE查找MySQL中的SQL耗时瓶颈

[关闭]
~ ~