最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語(yǔ)言開發(fā)框架反射機(jī)制及常見函數(shù)示例詳解

 更新時(shí)間:2022年09月23日 16:37:38   作者:山與路  
這篇文章主要為大家介紹了Go語(yǔ)言開發(fā)框架反射機(jī)制及常見函數(shù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

基本介紹

  • 反射可以在運(yùn)行時(shí)動(dòng)態(tài)獲取變量的各種信息,比如變量的類型,類別
  • 如果是結(jié)構(gòu)體變量,還可以獲取到結(jié)構(gòu)體本身的信息
  • 通過反射,可以修改變量的值,可以調(diào)用關(guān)聯(lián)的方法
  • 使用反射,需要import("reflect")

示意圖

反射中常見函數(shù)和概念

reflect.TypeOf(變量名)

獲取變量的類型,返回reflect.Type類型

reflect.ValueOf(變量名)

獲取變量的值,返回reflect.Value類型reflect.Value是一個(gè)結(jié)構(gòu)體類型,通過reflect.Value,可以獲取到關(guān)于該變量的很多信息

變量.interface{}和reflect.Value是可以相互轉(zhuǎn)換的

基本使用

package main
import (
   "fmt"
   "reflect"
)
/*
1.編寫案例,對(duì)基本數(shù)據(jù)類型,interface{},reflect.Value進(jìn)行反射
2.編寫案例,對(duì)結(jié)構(gòu)體,interface{},reflect.Value進(jìn)行反射
*/
func reflectTest(b interface{}){
   //打印出傳參的type,kind,value
   fmt.Printf("b的類型為%v,b的kind為%v,value為%v\n",reflect.TypeOf(b),reflect.ValueOf(b).Kind(),reflect.ValueOf(b))	//b的類型為int,b的kind為int,value為100
   //reflect.TypeOf(),reflect.ValueOf()返回的類型
   fmt.Printf("reflect.TypeOf()返回類型為%T,reflect.ValueOf()返回類型為%T\n",reflect.TypeOf(b),reflect.ValueOf(b)) //reflect.TypeOf()返回類型為*reflect.rtype,reflect.ValueOf()返回類型為reflect.Value
}
type Student struct {
   Name string
   age int
}
func reflectTest2(b interface{}){
   rTyp:=reflect.TypeOf(b)
   fmt.Println(rTyp) //main.Student
   rVal:=reflect.ValueOf(b)
   //將rVal轉(zhuǎn)換成interface{}
   iV:=rVal.Interface()
   fmt.Printf("iv=%v type=%T\n",iV,iV) //iv={張三 18} type=main.Student
   //因?yàn)镚o語(yǔ)言是靜態(tài)語(yǔ)言,所以不能直接獲取結(jié)構(gòu)體中指定的值,所以我需要將其斷言成需要的類型
   stu,ok:=iV.(Student)
   if ok{
   	fmt.Printf(stu.Name,stu.age)  //張三%!(EXTRA int=18)
   }
}
func main() {
   //1.編寫案例,對(duì)基本數(shù)據(jù)類型,interface{},reflect.Value進(jìn)行反射
   var num int =100
   reflectTest(num)
   //2.編寫案例,對(duì)結(jié)構(gòu)體,interface{},reflect.Value進(jìn)行反射
   stu:=Student{
   	Name: "張三",
   	age:  18,
   }
   reflectTest2(stu)
}

反射注意事項(xiàng)

  • reflect.ValueKind,獲取的變量的類別,返回的是一個(gè)常量
  • Type是類型,Kind是類別,Type和Kind可能是相同的,也可能是不同的,例如結(jié)構(gòu)體
  • 通過反射可以在讓變量在interface{}和reflect.Value之間相互轉(zhuǎn)換
  • 通過反射的方式獲取變量的值(并返回對(duì)應(yīng)的類型),要求數(shù)據(jù)類型匹配,比如x是int,那么就應(yīng)該使用reflect.Value(x).Int(),而不能使用其他的,否則報(bào)panic
  • 通過反射來修改變量,注意當(dāng)使用Setxxx方法來設(shè)置需要通過對(duì)應(yīng)的指針類型來完成,這樣才能改變傳入變量的值,同時(shí)需要使用到reflect.Value.Elem()方法

反射的最佳實(shí)踐

使用反射來遍歷結(jié)構(gòu)體的字段,調(diào)用結(jié)構(gòu)體的方法,并獲取結(jié)構(gòu)體標(biāo)簽的值

package main
import (
	"fmt"
	"reflect"
)
//定義了一個(gè)Monster結(jié)構(gòu)體
type Monster struct {
	Name  string `json:"name"`
	Age   int `json:"monster_age"`
	Score float32 `json:"成績(jī)"`
	Sex   string
}
//方法,返回兩個(gè)數(shù)的和
func (s Monster) GetSum(n1, n2 int) int {
	return n1 + n2
}
//方法, 接收四個(gè)值,給s賦值
func (s Monster) Set(name string, age int, score float32, sex string) {
	s.Name = name
	s.Age = age
	s.Score = score
	s.Sex = sex
}
//方法,顯示s的值
func (s Monster) Print() {
	fmt.Println("---start~----")
	fmt.Println(s)
	fmt.Println("---end~----")
}
func TestStruct(a interface{}) {
	//獲取reflect.Type 類型
	typ := reflect.TypeOf(a)
	//獲取reflect.Value 類型
	val := reflect.ValueOf(a)
	//獲取到a對(duì)應(yīng)的類別
	kd := val.Kind()
	//如果傳入的不是struct,就退出
	if kd !=  reflect.Struct {
		fmt.Println("expect struct")
		return
	}
	//獲取到該結(jié)構(gòu)體有幾個(gè)字段
	num := val.NumField()
	fmt.Printf("struct has %d fields\n", num) //4
	//變量結(jié)構(gòu)體的所有字段
	for i := 0; i < num; i++ {
		fmt.Printf("Field %d: 值為=%v\n", i, val.Field(i))
		//獲取到struct標(biāo)簽, 注意需要通過reflect.Type來獲取tag標(biāo)簽的值
		tagVal := typ.Field(i).Tag.Get("json")
		//如果該字段于tag標(biāo)簽就顯示,否則就不顯示
		if tagVal != "" {
			fmt.Printf("Field %d: tag為=%v\n", i, tagVal)
		}
	}
	//獲取到該結(jié)構(gòu)體有多少個(gè)方法
	numOfMethod := val.NumMethod()
	fmt.Printf("struct has %d methods\n", numOfMethod)
	//var params []reflect.Value
	//方法的排序默認(rèn)是按照 函數(shù)名的排序(ASCII碼)
	val.Method(1).Call(nil) //獲取到第二個(gè)方法。調(diào)用它
	//調(diào)用結(jié)構(gòu)體的第1個(gè)方法Method(0)
	var params []reflect.Value  //聲明了 []reflect.Value
	params = append(params, reflect.ValueOf(10))
	params = append(params, reflect.ValueOf(40))
	res := val.Method(0).Call(params) //傳入的參數(shù)是 []reflect.Value, 返回[]reflect.Value
	fmt.Println("res=", res[0].Int()) //返回結(jié)果, 返回的結(jié)果是 []reflect.Value*/
}
func main() {
	//創(chuàng)建了一個(gè)Monster實(shí)例
	var a Monster = Monster{
		Name:  "黃鼠狼精",
		Age:   400,
		Score: 30.8,
	}
	//將Monster實(shí)例傳遞給TestStruct函數(shù)
	TestStruct(a)	
}

以上就是Go語(yǔ)言開發(fā)框架反射機(jī)制及常見函數(shù)示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Go開發(fā)框架反射機(jī)制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • gRPC超時(shí)攔截器實(shí)現(xiàn)示例

    gRPC超時(shí)攔截器實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了gRPC超時(shí)攔截器實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Golang AGScheduler動(dòng)態(tài)持久化任務(wù)調(diào)度的強(qiáng)大庫(kù)使用實(shí)例

    Golang AGScheduler動(dòng)態(tài)持久化任務(wù)調(diào)度的強(qiáng)大庫(kù)使用實(shí)例

    這篇文章主要為大家介紹了Golang AGScheduler動(dòng)態(tài)持久化任務(wù)調(diào)度的強(qiáng)大庫(kù)使用實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • Golang import本地包和導(dǎo)入問題相關(guān)詳解

    Golang import本地包和導(dǎo)入問題相關(guān)詳解

    這篇文章主要介紹了Golang import本地包和導(dǎo)入問題相關(guān)詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • Go語(yǔ)言如何通過通信共享內(nèi)存

    Go語(yǔ)言如何通過通信共享內(nèi)存

    這篇文章主要為大家介紹了Go語(yǔ)言如何通過通信共享內(nèi)存實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • 用Go語(yǔ)言編寫一個(gè)簡(jiǎn)單的分布式系統(tǒng)

    用Go語(yǔ)言編寫一個(gè)簡(jiǎn)單的分布式系統(tǒng)

    這篇文章主要介紹了用Go語(yǔ)言編寫一個(gè)簡(jiǎn)單的分布式系統(tǒng),文中的代碼示例講解的非常詳細(xì),對(duì)我們的學(xué)習(xí)或工作有一定的幫助,感興趣的小伙伴跟著小編一起來看看吧
    2023-08-08
  • Debian 多版本共存 Go 安裝教程

    Debian 多版本共存 Go 安裝教程

    這篇文章介紹了在Debian系統(tǒng)上實(shí)現(xiàn)多版本Go共存的詳細(xì)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-04-04
  • Go語(yǔ)言結(jié)構(gòu)化日志slog的用法解析

    Go語(yǔ)言結(jié)構(gòu)化日志slog的用法解析

    go?1.21.0?版本引入了一個(gè)新的包?log/slog,該包提供了結(jié)構(gòu)化日志的功能,本文小編就來和大家聊聊log/slog?包的使用,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-10-10
  • Gin框架中的PostForm用法及說明

    Gin框架中的PostForm用法及說明

    這篇文章主要介紹了Gin框架中的PostForm用法及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Goland使用Go Modules創(chuàng)建/管理項(xiàng)目的操作

    Goland使用Go Modules創(chuàng)建/管理項(xiàng)目的操作

    這篇文章主要介紹了Goland使用Go Modules創(chuàng)建/管理項(xiàng)目的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • gorm整合進(jìn)go-zero的實(shí)現(xiàn)方法

    gorm整合進(jìn)go-zero的實(shí)現(xiàn)方法

    go-zero提供的代碼生成器里面,沒有提供orm框架操作,但是提供了遍歷的緩存操作,所以可以利用gorm當(dāng)作一個(gè)sql語(yǔ)句的生成器,把生成后的sql語(yǔ)句放到go-zero生成的模板中去執(zhí)行,對(duì)gorm整合進(jìn)go-zero的實(shí)現(xiàn)方法感興趣的朋友一起看看吧
    2022-03-03

最新評(píng)論

日喀则市| 河北省| 泸定县| 三原县| 疏勒县| 苏尼特右旗| 南和县| 汝南县| 高安市| 巧家县| 泗阳县| 加查县| 宁津县| 石门县| 哈尔滨市| 太保市| 武义县| 木里| 东安县| 镇康县| 蒙山县| 磴口县| 阿城市| 佳木斯市| 阜城县| 乌拉特后旗| 灯塔市| 明光市| 汪清县| 互助| 汾西县| 宜良县| 德保县| 潮安县| 孝昌县| 博兴县| 永吉县| 高阳县| 建阳市| 青海省| 滦平县|