" />

欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語言反射reflect.Value實(shí)現(xiàn)方法的調(diào)用

 更新時(shí)間:2022年05月31日 10:31:11   作者:starine  
本文主要介紹了Go語言反射reflect.Value實(shí)現(xiàn)方法的調(diào)用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

引言

這算是一個(gè)高級(jí)用法了,前面我們只說到對(duì)類型、變量的幾種反射的用法,包括如何獲取其值、其類型、以及如何重新設(shè)置新值。但是在項(xiàng)目應(yīng)用中,另外一個(gè)常用并且屬于高級(jí)的用法,就是通過reflect來進(jìn)行方法【函數(shù)】的調(diào)用。比如我們要做框架工程的時(shí)候,需要可以隨意擴(kuò)展方法,或者說用戶可以自定義方法,那么我們通過什么手段來擴(kuò)展讓用戶能夠自定義呢?關(guān)鍵點(diǎn)在于用戶的自定義方法是未可知的,因此我們可以通過reflect來搞定。

func (Value) Call

func (v Value) Call(in []Value) []Value

Call方法使用輸入的參數(shù)in調(diào)用v持有的函數(shù)。例如,如果len(in) == 3,v.Call(in)代表調(diào)用v(in[0], in[1], in[2])(其中Value值表示其持有值)。如果v的Kind不是Func會(huì)panic。它返回函數(shù)所有輸出結(jié)果的Value封裝的切片。和go代碼一樣,每一個(gè)輸入實(shí)參的持有值都必須可以直接賦值給函數(shù)對(duì)應(yīng)輸入?yún)?shù)的類型。如果v持有值是可變參數(shù)函數(shù),Call方法會(huì)自行創(chuàng)建一個(gè)代表可變參數(shù)的切片,將對(duì)應(yīng)可變參數(shù)的值都拷貝到里面。

通過反射,調(diào)用方法。

先獲取結(jié)構(gòu)體對(duì)象,然后調(diào)用結(jié)構(gòu)體的方法。

示例代碼:

package main

import (
   "fmt"
   "reflect"
)

type Person struct {
   Name string
   Age int
   Sex string
}

func (p Person)Say(msg string)  {
   fmt.Println("hello,",msg)
}
func (p Person)PrintInfo()  {
   fmt.Printf("姓名:%s,年齡:%d,性別:%s\n",p.Name,p.Age,p.Sex)
}

func (p Person) Test(i,j int,s string){
   fmt.Println(i,j,s)
}

// 如何通過反射來進(jìn)行方法的調(diào)用?
// 本來可以用結(jié)構(gòu)體對(duì)象.方法名稱()直接調(diào)用的,
// 但是如果要通過反射,
// 那么首先要將方法注冊(cè),也就是MethodByName,然后通過反射調(diào)動(dòng)mv.Call

func main() {
   p2 := Person{"王富貴",20,"男"}
   // 1. 要通過反射來調(diào)用起對(duì)應(yīng)的方法,必須要先通過reflect.ValueOf(interface)來獲取到reflect.Value,
   // 得到“反射類型對(duì)象”后才能做下一步處理
   getValue := reflect.ValueOf(p2)

   // 2.一定要指定參數(shù)為正確的方法名
   // 先看看沒有參數(shù)的調(diào)用方法

   methodValue1 := getValue.MethodByName("PrintInfo")
   fmt.Printf("Kind : %s, Type : %s\n",methodValue1.Kind(),methodValue1.Type())
   methodValue1.Call(nil) //沒有參數(shù),直接寫nil

   args1 := make([]reflect.Value, 0) //或者創(chuàng)建一個(gè)空的切片也可以
   methodValue1.Call(args1)

   // 有參數(shù)的方法調(diào)用
   methodValue2 := getValue.MethodByName("Say")
   fmt.Printf("Kind : %s, Type : %s\n",methodValue2.Kind(),methodValue2.Type())
   args2 := []reflect.Value{reflect.ValueOf("反射機(jī)制")}
   methodValue2.Call(args2)

   methodValue3 := getValue.MethodByName("Test")
   fmt.Printf("Kind : %s, Type : %s\n",methodValue3.Kind(),methodValue3.Type())
   args3 := []reflect.Value{reflect.ValueOf(5), reflect.ValueOf(2),reflect.ValueOf("you")}

   methodValue3.Call(args3)
}

運(yùn)行結(jié)果:

Kind : func, Type : func()
姓名:王富貴,年齡:20,性別:男
姓名:王富貴,年齡:20,性別:男
Kind : func, Type : func(string)
hello, 反射機(jī)制
Kind : func, Type : func(int, int, string)
5 2 you

通過反射,調(diào)用函數(shù)。

首先我們要先確認(rèn)一點(diǎn),函數(shù)像普通的變量一樣,之前的章節(jié)中我們?cè)谥v到函數(shù)的本質(zhì)的時(shí)候,是可以把函數(shù)作為一種變量類型的,而且是引用類型。如果說Fun()是一個(gè)函數(shù),那么f1 := Fun也是可以的,那么f1也是一個(gè)函數(shù),如果直接調(diào)用f1(),那么運(yùn)行的就是Fun()函數(shù)。

那么我們就先通過ValueOf()來獲取函數(shù)的反射對(duì)象,可以判斷它的Kind,是一個(gè)func,那么就可以執(zhí)行Call()進(jìn)行函數(shù)的調(diào)用。

示例代碼:

package main

import (
   "fmt"
   "reflect"
)

func main() {
   //函數(shù)的反射
   f1 := fun1
   value := reflect.ValueOf(f1)
   fmt.Printf("Kind : %s , Type : %s\n",value.Kind(),value.Type()) //Kind : func , Type : func()

   value2 := reflect.ValueOf(fun2)
   fmt.Printf("Kind : %s , Type : %s\n",value2.Kind(),value2.Type()) //Kind : func , Type : func(int, string)

   //通過反射調(diào)用函數(shù)
   value.Call(nil)

   value2.Call([]reflect.Value{reflect.ValueOf("hello"),reflect.ValueOf(61)})

}

func fun1(){
   fmt.Println("我是函數(shù)fun1(),無參的。")
}

func fun2(s string, i int){
   fmt.Println("我是函數(shù)fun2(),有參數(shù):",s,i)
}

運(yùn)行結(jié)果:

Kind : func , Type : func()
Kind : func , Type : func(string, int)
我是函數(shù)fun1(),無參的。
我是函數(shù)fun2(),有參數(shù): hello 61

到此這篇關(guān)于Go語言反射reflect.Value實(shí)現(xiàn)方法的調(diào)用的文章就介紹到這了,更多相關(guān)Go 反射方法調(diào)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang中的三個(gè)點(diǎn) ''...''的用法示例詳解

    golang中的三個(gè)點(diǎn) ''...''的用法示例詳解

    這篇文章主要介紹了golang中的三個(gè)點(diǎn) '...' 的用法示例詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Go單體服務(wù)開發(fā)最佳實(shí)踐總結(jié)

    Go單體服務(wù)開發(fā)最佳實(shí)踐總結(jié)

    這篇文章主要介紹了Go單體服務(wù)開發(fā)最佳實(shí)踐,通過本文詳細(xì)跟大家分享一下如何使用?go-zero?快速開發(fā)一個(gè)有多個(gè)模塊的單體服務(wù),需要的朋友可以參考下
    2022-04-04
  • Go 庫性能分析工具pprof

    Go 庫性能分析工具pprof

    這篇文章主要為大家介紹了Go 庫性能分析工具pprof,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • golang環(huán)形隊(duì)列實(shí)現(xiàn)代碼示例

    golang環(huán)形隊(duì)列實(shí)現(xiàn)代碼示例

    這篇文章主要介紹了golang環(huán)形隊(duì)列實(shí)現(xiàn)代碼示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Golang文件讀寫操作詳情

    Golang文件讀寫操作詳情

    這篇文章主要介紹了Golang文件讀寫操作詳情,文件是數(shù)據(jù)源(保存數(shù)據(jù)的地方)的一種,文件最主要的作用就是保存數(shù)據(jù),文件在程序中是以流的形式來操作的,更多詳細(xì)內(nèi)容需要的朋友可以參考一下
    2022-07-07
  • 詳解Go語言如何使用標(biāo)準(zhǔn)庫sort對(duì)切片進(jìn)行排序

    詳解Go語言如何使用標(biāo)準(zhǔn)庫sort對(duì)切片進(jìn)行排序

    Sort?標(biāo)準(zhǔn)庫提供了對(duì)基本數(shù)據(jù)類型的切片和自定義類型的切片進(jìn)行排序的函數(shù)。今天主要分享的內(nèi)容是使用?Go?標(biāo)準(zhǔn)庫?sort?對(duì)切片進(jìn)行排序,感興趣的可以了解一下
    2022-12-12
  • golang解析yaml文件操作

    golang解析yaml文件操作

    這篇文章主要介紹了golang解析yaml文件操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 基于golang時(shí)間轉(zhuǎn)換的問題

    基于golang時(shí)間轉(zhuǎn)換的問題

    下面小編就為大家?guī)硪黄趃olang時(shí)間轉(zhuǎn)換的問題。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • 如何在Go中使用切片容量和長(zhǎng)度

    如何在Go中使用切片容量和長(zhǎng)度

    這篇文章主要介紹了如何在Go中使用切片容量和長(zhǎng)度,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • 詳解Go?sync?同步原語

    詳解Go?sync?同步原語

    Go?中不僅有?channel?這種?CSP?同步機(jī)制,還有?sync.Mutex、sync.WaitGroup?等比較原始的同步原語,使用它們,可以更靈活的控制數(shù)據(jù)同步和多協(xié)程并發(fā),這篇文章主要介紹了Go?sync?同步原語,需要的朋友可以參考下
    2023-12-12

最新評(píng)論