一文初探Go語(yǔ)言中的reflect反射包
reflect 反射包
針對(duì)反射,Go
提供了 reflect
包,使用這個(gè)包里的函數(shù)可以在程序運(yùn)行時(shí)獲取和更新未知變量的值,操作未知變量的方法等。
reflect
包核心的兩個(gè)重要類型:
reflect.Type
:Type
是一個(gè)接口,不同數(shù)據(jù)類型有著不同的結(jié)構(gòu)體實(shí)現(xiàn)。這個(gè)接口用于操作變量的類型信息,類型的信息只能讀取。reflect.Value
:Value
是一個(gè)結(jié)構(gòu)體,通過(guò)這個(gè)結(jié)構(gòu)體可以操作變量的值。
TypeOf(i) 和 ValueOf(i)
reflect.TypeOf(i any) Type
:獲取變量的類型,返回一個(gè)reflect.Type
類型。reflect.ValueOf(i any) Value
:獲取變量的值,返回reflect.Value
類型,通過(guò)Value
可以對(duì)獲取變量更多的信息。
案例1:獲取變量的類別和類型信息
import ( "fmt" "reflect" ) type User struct { Name string } func main() { user := User{ Name: "cmy", } func4Reflect(user) } func func4Reflect(data any) { typ := reflect.TypeOf(data) fmt.Println("類別:", typ.Kind()) // 類別: struct fmt.Println("類型:", typ.Name()) // 類型: User }
- 通過(guò)
TypeOf()
函數(shù)獲取data
的類型信息,然后調(diào)用Kind()
和Name()
方法分別獲取data
變量的類別和類型信息。 - 根據(jù)返回結(jié)果可知,
Kind()
返回的是Go
的數(shù)據(jù)類型,而Name()
返回的是我們自定義的數(shù)據(jù)類型。 - 根據(jù)
Kind()
返回值的特點(diǎn),可以用于判斷變量屬于 Go 的哪種數(shù)據(jù)類型,用于類型限制等場(chǎng)景。
案例2:修改基本數(shù)據(jù)類型變量的值
import ( "fmt" "reflect" ) func main() { num1 := 666 fmt.Println("num1 原值:", num1) func4Reflect(&num1) fmt.Println("num1 修改后的值:", num1) num2 := 0.5 fmt.Println("num2 原值:", num2) func4Reflect(&num2) fmt.Println("num2 修改后的值:", num2) str := "go" fmt.Println("str 原值:", str) func4Reflect(&str) fmt.Println("str 修改后的值:", str) } func func4Reflect(data any) { typ := reflect.TypeOf(data) val := reflect.ValueOf(data) switch typ.Elem().Kind() { case reflect.Int: val.Elem().SetInt(888) case reflect.Float64: val.Elem().SetFloat(3.14) case reflect.String: val.Elem().SetString("Golang") } }
通過(guò) ValueOf()
函數(shù)獲取 data
變量的值信息,然后結(jié)合 reflect.Type.Kind()
方法,對(duì)不同類型的變量的值進(jìn)行修改操作(只舉三種類型的例子):
int
類型 → 使用SetInt(val)
方法對(duì)值進(jìn)行修改。float64
→ 使用SetFloat(val)
方法對(duì)值進(jìn)行修改。string
類型 → 使用SetString(val)
方法對(duì)值進(jìn)行修改。
data
必須是指針類型,否則無(wú)法通過(guò)反射修改。
由于是指針類型,因此需要調(diào)用 Elem()
方法獲取到指針指向的變量,才能修改變量的值。
案例3:通過(guò)反射獲取結(jié)構(gòu)體的字段名、字段類型和字段的值
import ( "fmt" "reflect" ) type User struct { Name string Age int } func main() { user := User{ Name: "cmy", Age: 18, } func4Reflect(user) } func func4Reflect(data any) { typ := reflect.TypeOf(data) val := reflect.ValueOf(data) // 獲取結(jié)構(gòu)體字段的數(shù)量 numField := val.NumField() for i := 0; i < numField; i++ { fmt.Println("字段名稱:", typ.Field(i).Name) fmt.Println("字段類型:", typ.Field(i).Type.Name()) fmt.Println("字段值:", val.Field(i).Interface()) fmt.Println("----------------------------") } }
- 首先通過(guò)
TypeOf()
和ValueOf()
獲取到結(jié)構(gòu)體的類型信息和值信息。 - 其次通過(guò)
Value.NumField()
方法獲取到結(jié)構(gòu)體字段的數(shù)量。 - 接著遍歷結(jié)構(gòu)體的字段,通過(guò)
Type.Field(i)
方法,傳入索引,獲取到對(duì)應(yīng)字段的類型信息,通過(guò)Name
屬性獲取字段名,Type.Name()
獲取字段類型。 - 最后通過(guò)
Value.Field(i)
方法,傳入索引,獲取到對(duì)應(yīng)字段的值信息,通過(guò)Interface()
方法獲取字段實(shí)際的值。
小結(jié)
本文首先介紹了 reflect
包里兩個(gè)重要的類型 reflect.Type
和 reflect.Value
,簡(jiǎn)單說(shuō)明了它們的作用;其次介紹了TypeOf(i)
和 ValueOf(i)
兩個(gè)函數(shù);最后通過(guò)三個(gè)案例介紹了它們的使用場(chǎng)景。
到此這篇關(guān)于一文初探Go語(yǔ)言中的reflect反射包的文章就介紹到這了,更多相關(guān)Go語(yǔ)言reflect反射包內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mac下Vs code配置Go語(yǔ)言環(huán)境的詳細(xì)過(guò)程
這篇文章給大家介紹Mac下Vs code配置Go語(yǔ)言環(huán)境的詳細(xì)過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2021-07-07Go構(gòu)建器模式構(gòu)建復(fù)雜對(duì)象方法實(shí)例
本文介紹了構(gòu)建器模式,如何通過(guò)構(gòu)建器對(duì)象構(gòu)建復(fù)雜業(yè)務(wù)對(duì)象的方法實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12golang中select語(yǔ)句的簡(jiǎn)單實(shí)例
Go的select語(yǔ)句是一種僅能用于channl發(fā)送和接收消息的專用語(yǔ)句,此語(yǔ)句運(yùn)行期間是阻塞的,下面這篇文章主要給大家介紹了關(guān)于golang中select語(yǔ)句的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06Go中時(shí)間與時(shí)區(qū)問(wèn)題的深入講解
go語(yǔ)言中如果不設(shè)置指定的時(shí)區(qū),通過(guò)time.Now()獲取到的就是本地時(shí)區(qū),下面這篇文章主要給大家介紹了關(guān)于Go中時(shí)間與時(shí)區(qū)問(wèn)題的相關(guān)資料,需要的朋友可以參考下2021-12-12基于context.Context的Golang?loader緩存請(qǐng)求放大問(wèn)題解決
這篇文章主要為大家介紹了基于context.Context的Golang?loader緩存請(qǐng)求放大解決方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05詳解Go程序添加遠(yuǎn)程調(diào)用tcpdump功能
這篇文章主要介紹了go程序添加遠(yuǎn)程調(diào)用tcpdump功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05Go并發(fā)編程之sync.Once使用實(shí)例詳解
sync.Once使用起來(lái)很簡(jiǎn)單, 下面是一個(gè)簡(jiǎn)單的使用案例,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2021-11-11Go擴(kuò)展原語(yǔ)之SingleFlight的用法詳解
Go語(yǔ)言擴(kuò)展包同步原語(yǔ)singleflight.Group能夠再一個(gè)服務(wù)中抑制對(duì)下游的多次重復(fù)請(qǐng)求,它能夠限制對(duì)同一個(gè)鍵值對(duì)的多次重復(fù)請(qǐng)求,減少對(duì)下游的瞬時(shí)流量,接下來(lái)小編就給大家講講Go SingleFlight的具體用法,需要的朋友可以參考下2023-07-07基于Go?goroutine實(shí)現(xiàn)一個(gè)簡(jiǎn)單的聊天服務(wù)
對(duì)于聊天服務(wù),想必大家都不會(huì)陌生,因?yàn)樵谖覀兊纳钪薪?jīng)常會(huì)用到,本文我們用?Go?并發(fā)來(lái)實(shí)現(xiàn)一個(gè)聊天服務(wù)器,這個(gè)程序可以讓一些用戶通過(guò)服務(wù)器向其它所有用戶廣播文本消息,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06