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

一文帶你掌握Golang的反射基礎(chǔ)

 更新時間:2023年02月17日 11:24:36   作者:TtrOps  
go的反射是由其標準庫中的reflect包實現(xiàn),該reflect包實現(xiàn)了在運行時進行反射的能力,本篇主要介紹了reflect的常用的幾個方法,希望對大家有所幫助

什么是反射

反射的機制是在運行時可以獲取到其變量的類型和值,且可以在運行時對其變量類型和值進行檢查,可以對其值進行修改。這種機制,其實在編寫業(yè)務(wù)代碼時是比較少用到的,那么在框架中,使用的反射的機制是比較常見,如web框架、Orm框架,實現(xiàn)通用性的目的。

go的反射

go的反射是由其標準庫中的reflect包實現(xiàn),該reflect包實現(xiàn)了在運行時進行反射的能力,本篇先講解一下reflect的常用的幾個方法,下篇模擬一些貼近實際的應(yīng)用場景來剖析到底怎么用。

實戰(zhàn)reflect包中常用的幾個類型和方法

1.通過反射獲取變量的類型(Type)

package?main

import?(
?"fmt"
?"reflect"
)

func?main()?{
?fmt.Println("公眾號搜索:不背鍋運維")

?a?:=?100.89
?b?:=?"hello"
?//獲取變量a和b的類型,即使用reflect.TypeOf反射出了基本數(shù)據(jù)類型的變量的類型。
?fmt.Println(reflect.TypeOf(a))?//float64
?fmt.Println(reflect.TypeOf(b))?//string

?//?反射獲取結(jié)構(gòu)體類型信息
?type?User?struct?{
??Name?string
??Age??int
?}
?u?:=?User{"tantianran",?18}
?fmt.Println(reflect.TypeOf(u))?//main.User
}

2.使用反射獲取變量對應(yīng)的值(Value)

package?main

import?(
?"fmt"
?"reflect"
)

func?main()?{
?fmt.Println("公眾號搜索:不背鍋運維")

?a?:=?100.89
?b?:=?"hello"
?//使用反射獲取變量的Value。
?fmt.Println(reflect.ValueOf(a))?//100.89
?fmt.Println(reflect.ValueOf(b))?//hello

?//?使用反射獲取結(jié)構(gòu)體變量的Value
?type?User?struct?{
??Name?string
??Age??int
?}
?u?:=?User{"tantianran",?18}
?fmt.Println(reflect.ValueOf(u))?//{tantianran?18}
}

3.TypeOf()方法獲取到變量的類型后,再調(diào)用它的Kind()方法可以將返回的結(jié)果用來進行類型的判斷

package?main

import?(
?"fmt"
?"reflect"
)

func?main()?{
?fmt.Println("公眾號搜索:不背鍋運維")

?a?:=?100.89
?//通過反射獲取變量a的類型
?aType?:=?reflect.TypeOf(a)
?fmt.Println(aType)?//float64

?//返回變量a的Type后,調(diào)用它的Kind()方法獲取該類型的詳細信息
?aKind?:=?aType.Kind()
?fmt.Println(aKind)?//float64

?//?Kind()方法返回的結(jié)果主要用途是可以用來進行類型判斷
?if?aKind?==?reflect.Float64?{?//?使用reflect包里面的數(shù)據(jù)類型Float64
??fmt.Println("is?float64")
?}?else?{
??fmt.Println("no")
?}
}

注意,TypeOf()方法是不支持進行類型判斷的,如if aType == reflect.Float64,此時會報錯。

4.通過Elem()方法獲取變量的指針所指向的對象

注意,先傳入變量的地址給ValueOf方法,然后調(diào)用Elem()方法獲取該變量的指針所指向的對象

package?main

import?(
?"fmt"
?"reflect"
)

func?main()?{
?fmt.Println("公眾號搜索:不背鍋運維")

?a?:=?100.89
?//?ValueOf傳入的是地址,調(diào)用Elem()方法可以獲取變量的指針指向的對象
?PaValue?:=?reflect.ValueOf(&a)?//傳入變量a的地址
?fmt.Println(PaValue)?//0xc0000180a0

?aElem?:=?PaValue.Elem()
?fmt.Println(aElem)??//100.89
}

5.通過反射修改變量的值

方式一:使用具體類型的設(shè)置值的方法,如SetInt,SetString等

package?main

import?(
?"fmt"
?"log"
?"reflect"
)

func?main()?{
?fmt.Println("公眾號搜索:不背鍋運維")

?//聲明int類型變量和賦值
?var?x?int?=?100
?fmt.Println("修改之前?",?x)

?//通過反射,傳入變量的地址,并通過Elem方法獲取指向該變量地址的值
?v?:=?reflect.ValueOf(&x).Elem()

?//判斷是否可以修改變量的值,使用CanSet方法獲取是否可以修改該變量的值,可以是true,反之false
?if?v.CanSet()?{
??v.SetInt(89)
?}?else?{
??log.Println("變量的值不可修改")
?}

?fmt.Println("修改之后",?x)
}

方式2:使用Set方法

package?main

import?(
?"fmt"
?"log"
?"reflect"
)

func?main()?{
?fmt.Println("公眾號搜索:不背鍋運維")

?//聲明int類型變量和賦值
?var?x?int?=?100
?fmt.Println("修改之前?",?x)

?//通過反射,傳入變量的地址,并通過Elem方法獲取指向該變量地址的值
?v?:=?reflect.ValueOf(&x).Elem()

?//判斷是否可以修改變量的值,使用CanSet方法獲取是否可以修改該變量的值,可以是true,反之false
?if?v.CanSet()?{
??a?:=?reflect.ValueOf(67)?//使用Set方法修改值,Set方法接收的是ValueOf的返回值
??v.Set(a)
?}?else?{
??log.Println("變量的值不可修改")
?}

?fmt.Println("修改之后",?x)
}

注意:想要通過反射修改變量的值,那么必須在reflect.ValueOf傳入變量的地址,而不能傳入變量的值。

6.通過反射獲取結(jié)構(gòu)體變量的類型和值

package?main

import?(
?"fmt"
?"reflect"
)

type?User?struct?{
?Name?string
?Age??int
}

func?(u?User)?show()?{
?fmt.Println("Type,?",?reflect.TypeOf(u))
?fmt.Println("Value,?",?reflect.ValueOf(u))
}

func?main()?{
?fmt.Println("公眾號搜索:不背鍋運維")

?u?:=?User{Name:?"ttr",?Age:?18}
?u.show()
}

7.對比一下反射中的方法TypeOf()和Kind()輸出的區(qū)別

package?main

import?(
?"fmt"
?"reflect"
)

type?User?struct?{
?Name?string
?Age??int
}

func?(u?User)?show()?{
?uType?:=?reflect.TypeOf(u)
?fmt.Println("Type,?",?uType)
?uKind?:=?uType.Kind()
?fmt.Println("Kind?,?",?uKind)
}

func?main()?{
?fmt.Println("公眾號搜索:不背鍋運維")

?u?:=?User{Name:?"ttr",?Age:?18}
?u.show()
}

輸出:

Type,  main.User
Kind ,  struct

main.User表示是哪個結(jié)構(gòu)體類型,struct表示是屬于哪一類數(shù)據(jù)類型

package?main

import?(
?"fmt"
?"reflect"
)

type?User?struct?{
?Name?string
?Age??int
}

func?show(i?interface{})?{
?iType?:=?reflect.TypeOf(i)
?iKind?:=?iType.Kind()
?if?iKind?!=?reflect.Struct?{
??panic("Not?a?structure?type")
?}?else?{
??val?:=?reflect.ValueOf(i)
??for?i?:=?0;?i?<?iType.NumField();?i++?{
???fmt.Println("FiledName:",?iType.Field(i).Name,?"FiledType:",?iType.Field(i).Type,?"Value:",?val.Field(i))
??}
?}
}

func?main()?{
?fmt.Println("公眾號搜索:不背鍋運維")
?
?u?:=?User{Name:?"ttr",?Age:?18}
?show(u)
}

輸出:

FiledName: Name FiledType: string Value: ttr
FiledName: Age FiledType: int Value: 18

NumField()方法獲取結(jié)構(gòu)體內(nèi)的字段數(shù)量,iType.Field(i).Name獲取結(jié)構(gòu)體字段名稱,iType.Field(i).Type獲取結(jié)構(gòu)體字段類型,val.Field(i))獲取結(jié)構(gòu)體字段中的值。

到此這篇關(guān)于一文帶你掌握Golang的反射基礎(chǔ)的文章就介紹到這了,更多相關(guān)Golang反射內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言Gin框架獲取請求參數(shù)的兩種方式

    Go語言Gin框架獲取請求參數(shù)的兩種方式

    在添加路由處理函數(shù)之后,就可以在路由處理函數(shù)中編寫業(yè)務(wù)處理代碼了,而編寫業(yè)務(wù)代碼第一件事一般就是獲取HTTP請求的參數(shù)吧,Gin框架在net/http包的基礎(chǔ)上封裝了獲取參數(shù)的方式,本文小編給大家介紹了獲取參數(shù)的兩種方式,需要的朋友可以參考下
    2024-01-01
  • go語言錯誤處理基本概念(創(chuàng)建返回)

    go語言錯誤處理基本概念(創(chuàng)建返回)

    這篇文章主要為大家介紹了go語言錯誤處理基本概念(創(chuàng)建返回),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • go+redis實現(xiàn)消息隊列發(fā)布與訂閱的詳細過程

    go+redis實現(xiàn)消息隊列發(fā)布與訂閱的詳細過程

    這篇文章主要介紹了go+redis實現(xiàn)消息隊列發(fā)布與訂閱,redis做消息隊列的缺點:沒有持久化,一旦消息沒有人消費,積累到一定程度后就會丟失,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • Golang回調(diào)函數(shù)與閉包和接口函數(shù)的定義及使用介紹

    Golang回調(diào)函數(shù)與閉包和接口函數(shù)的定義及使用介紹

    這篇文章主要介紹了Golang回調(diào)函數(shù)與閉包和接口函數(shù)的定義及使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-05-05
  • 詳解Go語言中用 os/exec 執(zhí)行命令的五種方法

    詳解Go語言中用 os/exec 執(zhí)行命令的五種方法

    這篇文章主要介紹了Go語言中用 os/exec 執(zhí)行命令的五種方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • go語言中匿名函數(shù)的作用域陷阱詳解

    go語言中匿名函數(shù)的作用域陷阱詳解

    GO語言的匿名函數(shù)(anonymous?function),其實就是閉包.是指不需要定義函數(shù)名的一種函數(shù)實現(xiàn)方式,下面這篇文章主要給大家介紹了關(guān)于go語言中匿名函數(shù)作用域陷阱的相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • Go語言map實現(xiàn)順序讀取

    Go語言map實現(xiàn)順序讀取

    當我們遍歷 map 時,那就是輸出的鍵值對順序是不確定的,本文主要介紹了Go語言map實現(xiàn)順序讀取, 文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 詳解Go語言中Goroutine退出機制的原理及使用

    詳解Go語言中Goroutine退出機制的原理及使用

    goroutine是Go語言提供的語言級別的輕量級線程,在我們需要使用并發(fā)時,我們只需要通過?go?關(guān)鍵字來開啟?goroutine?即可。本文就來詳細講講Goroutine退出機制的原理及使用,感興趣的可以了解一下
    2022-07-07
  • Golang實現(xiàn)http文件上傳小功能的案例

    Golang實現(xiàn)http文件上傳小功能的案例

    這篇文章主要介紹了Golang實現(xiàn)http文件上傳小功能的案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • golang進程在docker中OOM后hang住問題解析

    golang進程在docker中OOM后hang住問題解析

    這篇文章主要介紹了golang進程在docker中OOM后hang住問題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10

最新評論