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

一文帶你掌握Golang的反射基礎

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

什么是反射

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

go的反射

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

實戰(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

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

2.使用反射獲取變量對應的值(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

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

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

package?main

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

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

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

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

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

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

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

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

package?main

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

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

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

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

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

方式一:使用具體類型的設置值的方法,如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.通過反射獲取結構體變量的類型和值

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表示是哪個結構體類型,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()方法獲取結構體內的字段數(shù)量,iType.Field(i).Name獲取結構體字段名稱,iType.Field(i).Type獲取結構體字段類型,val.Field(i))獲取結構體字段中的值。

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

相關文章

  • Golang中使用Mqtt的方法示例

    Golang中使用Mqtt的方法示例

    本文介紹了Golang中使用paho.mqtt.golang庫實現(xiàn)MQTT客戶端與服務器的連接、訂閱和消息收發(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結構

    一文帶你理解Golang中的Time結構

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

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

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

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

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

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

    這篇文章主要為大家介紹了Go語言教程關于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 的基礎上,提供了更高級別的便利,極大地簡化了數(shù)據(jù)庫操作,本文章將介紹如何通過sqlx包來操作 MySQL 數(shù)據(jù)庫,感興趣的可以了解下
    2024-11-11

最新評論

山丹县| 青阳县| 营口市| 庆阳市| 万山特区| 伊吾县| 车险| 宜川县| 咸宁市| 阿拉善左旗| 安达市| 甘孜县| 曲麻莱县| 济源市| 汉阴县| 图们市| 广西| 吉水县| 纳雍县| 米林县| 明水县| 黔西县| 通辽市| 明光市| 栾川县| 湘潭县| 临夏市| 宕昌县| 荔浦县| 汉源县| 吐鲁番市| 霞浦县| 华安县| 黔江区| 西充县| 老河口市| 应城市| 潍坊市| 巴彦县| 黄骅市| 鸡西市|