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

一文帶你掌握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)文章

  • Golang中使用Mqtt的方法示例

    Golang中使用Mqtt的方法示例

    本文介紹了Golang中使用paho.mqtt.golang庫實現(xiàn)MQTT客戶端與服務(wù)器的連接、訂閱和消息收發(fā),具有一定的參考價值,感興趣的可以了解一下
    2025-02-02
  • Go語言框架Beego項目搭建的方法步驟

    Go語言框架Beego項目搭建的方法步驟

    這篇文章主要介紹了Go語言框架Beego項目搭建的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05
  • golang對etcd存取和數(shù)值監(jiān)測的實現(xiàn)

    golang對etcd存取和數(shù)值監(jiān)測的實現(xiàn)

    這篇文章主要介紹了golang對etcd存取和數(shù)值監(jiān)測的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-09-09
  • 一文帶你理解Golang中的Time結(jié)構(gòu)

    一文帶你理解Golang中的Time結(jié)構(gòu)

    根據(jù)golang的time包的文檔可以知道,golang的time結(jié)構(gòu)中存儲了兩種時鐘,一種是Wall?Clocks,一種是Monotonic?Clocks,下面我們就來簡單了解一下這兩種結(jié)構(gòu)吧
    2023-09-09
  • 基于Go語言實現(xiàn)一個并發(fā)下載器

    基于Go語言實現(xiàn)一個并發(fā)下載器

    這篇文章主要為大家詳細介紹了如何利用GO語言實現(xiàn)一個并發(fā)的文件下載器,可以在不重新啟動整個下載的情況下處理錯誤,感興趣的小伙伴可以了解一下
    2023-10-10
  • golang實現(xiàn)簡單工廠、方法工廠、抽象工廠三種設(shè)計模式

    golang實現(xiàn)簡單工廠、方法工廠、抽象工廠三種設(shè)計模式

    這篇文章介紹了golang實現(xiàn)簡單工廠、方法工廠、抽象工廠三種設(shè)計模式的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • Go語言七篇入門教程七GC垃圾回收三色標記

    Go語言七篇入門教程七GC垃圾回收三色標記

    這篇文章主要為大家介紹了Go語言教程關(guān)于GC垃圾回收三色標記的示例詳解,本篇文章是Go語言七篇入門教程系列文章,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-11-11
  • golang 之import和package的使用

    golang 之import和package的使用

    這篇文章主要介紹了golang 之import和package的使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-02-02
  • go swagger生成接口文檔使用教程

    go swagger生成接口文檔使用教程

    這篇文章主要為大家介紹了go swagger生成接口文檔使用教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • Go語言使用sqlx操作MySQL

    Go語言使用sqlx操作MySQL

    sqlx 包作為一個擴展庫,它在 database/sql 的基礎(chǔ)上,提供了更高級別的便利,極大地簡化了數(shù)據(jù)庫操作,本文章將介紹如何通過sqlx包來操作 MySQL 數(shù)據(jù)庫,感興趣的可以了解下
    2024-11-11

最新評論

浦城县| 仁布县| 磴口县| 称多县| 上高县| 新乡市| 湖北省| 平阳县| 寿光市| 浮梁县| 三江| 天长市| 盐池县| 辽宁省| 呼和浩特市| 平度市| 长阳| 朔州市| 廉江市| 武夷山市| 洪洞县| 凌云县| 庐江县| 汕尾市| 漠河县| 随州市| 鹿泉市| 宜都市| 巩留县| 肇源县| 北票市| 抚宁县| 张家口市| 安泽县| 讷河市| 开封县| 进贤县| 仙游县| 洪江市| 林芝县| 蒙城县|