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

Golang學(xué)習(xí)之反射機(jī)制的用法詳解

 更新時(shí)間:2022年06月01日 16:00:54   作者:LiberHome  
反射的本質(zhì)就是在程序運(yùn)行的時(shí)候,獲取對(duì)象的類型信息和內(nèi)存結(jié)語構(gòu),反射是把雙刃劍,功能強(qiáng)大但可讀性差。本文將詳細(xì)講講Golang中的反射機(jī)制,感興趣的可以了解一下

介紹

反射的本質(zhì)就是在程序運(yùn)行的時(shí)候,獲取對(duì)象的類型信息和內(nèi)存結(jié)構(gòu),反射是把雙刃劍,功能強(qiáng)大但可讀性差,反射代碼無法在編譯階段靜態(tài)發(fā)現(xiàn)錯(cuò)誤,反射的代碼常常比正常代碼效率低1~2個(gè)數(shù)量級(jí),如果在關(guān)鍵位置使用反射會(huì)直接導(dǎo)致代碼效率問題,所以,如非必要,不建議使用。

靜態(tài)類型是指在編譯的時(shí)候就能確定的類型(常見的變量聲明類型都是靜態(tài)類型);動(dòng)態(tài)類型是指在運(yùn)行的時(shí)候才能確定的類型(比如接口,也只有接口才有反射)。

使用反射的三個(gè)步驟:

  • 先有一個(gè)接口類型的變量
  • 把它轉(zhuǎn)成reflect對(duì)象 一般就是type 或者 value類型
  • 然后根據(jù)不同的情況調(diào)用相應(yīng)的函數(shù)

TypeOf() ValueOf()

為了說明其用法,先舉個(gè)最簡單的例子:

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var x float64 = 3.4
    fmt.Println("type : ", reflect.TypeOf(x))
    fmt.Println("value : ", reflect.ValueOf(x))
}

運(yùn)行結(jié)果是:

type :  float64
value :  3.4

獲取接口變量信息

事先知道原有類型的時(shí)候

舉個(gè)例子:

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var num float64 = 3.14
    //接口類型變量得到一個(gè)反射類型的變量
    value := reflect.ValueOf(num)
    //從一個(gè)反射類型對(duì)象得到接口類型變量
    conervtValue := value.Interface().(float64)
    fmt.Println(conervtValue)

    //pointer 包含了一個(gè)float64的指針類型
    pointer := reflect.ValueOf(&num)
    convertPointer := pointer.Interface().(*float64)
    fmt.Println(convertPointer)
}

運(yùn)行結(jié)果是:

3.14
0x1400012a008

事先不知道原有類型的時(shí)候

這時(shí)候我們一般需要遍歷探測一下Field

舉個(gè)例子:

package main

import (
    "fmt"
    "reflect"
)

type Person struct {
    Name   string
    Age    int
    Gender string
}

func (p Person) Say(msg string) {
    fmt.Println("hello, ", msg)
}

func (p Person) PrintInfo() {
    fmt.Printf("Name: %s, Age: %d, Gender: %s", p.Name, p.Age, p.Gender)
}
func main() {
    p1 := Person{"bill", 16, "Male"}
    GetMessage(p1)
}

//獲取input的信息  在這個(gè)函數(shù)中 輸入是空接口
//代表我們并不知道input的原始類型是什么 取決于函數(shù)調(diào)用的時(shí)候摻進(jìn)來什么參數(shù)
func GetMessage(input interface{}) {
    getType := reflect.TypeOf(input)
    fmt.Println("輸入數(shù)據(jù)的類型是: ", getType.Name())
    fmt.Println("輸入數(shù)據(jù)的種類是: ", getType.Kind())

    getValue := reflect.ValueOf(input)
    fmt.Println("all fields are: ", getValue)
}

運(yùn)行結(jié)果如下:

輸入數(shù)據(jù)的類型是:  Person
輸入數(shù)據(jù)的種類是:  struct
all fields are:  {bill 16 Male}

上面的例子,我們一口氣把所有的字段值全部打印出來了,但如果我們想挨個(gè)打印每個(gè)字段的名字,類型,數(shù)值我們應(yīng)該這樣做:

package main

import (
    "fmt"
    "reflect"
)

type Person struct {
    Name   string
    Age    int
    Gender string
}

func (p Person) Say(msg string) {
    fmt.Println("hello, ", msg)
}

func (p Person) PrintInfo() {
    fmt.Printf("Name: %s, Age: %d, Gender: %s", p.Name, p.Age, p.Gender)
}
func main() {
    p1 := Person{"bill", 16, "Male"}
    GetMessage(p1)
}

//獲取input的信息  在這個(gè)函數(shù)中 輸入是空接口
//代表我們并不知道input的原始類型是什么 取決于函數(shù)調(diào)用的時(shí)候摻進(jìn)來什么參數(shù)
func GetMessage(input interface{}) {
    getType := reflect.TypeOf(input)
    fmt.Println("輸入數(shù)據(jù)的類型是: ", getType.Name())
    fmt.Println("輸入數(shù)據(jù)的種類是: ", getType.Kind())

    getValue := reflect.ValueOf(input)
    fmt.Println("all fields are: ", getValue)

    //獲取字段
    for i := 0; i < getType.NumField(); i++ {
        field := getType.Field(i)
        value := getValue.Field(i).Interface()
        fmt.Printf("字段名稱: %s, 字段類型: %s, 字段值: %v\n ", field.Name, field.Type, value)
    }
}

運(yùn)行結(jié)果是:

輸入數(shù)據(jù)的類型是:  Person
輸入數(shù)據(jù)的種類是:  struct
all fields are:  {bill 16 Male}
字段名稱: Name, 字段類型: string, 字段值: bill
字段名稱: Age, 字段類型: int, 字段值: 16
字段名稱: Gender, 字段類型: string, 字段值: Male

如果我們還想獲取方法怎么辦呢?原理和上面差不多,不過我們需要把field改成method,舉個(gè)例子:

package main

import (
    "fmt"
    "reflect"
)

type Person struct {
    Name   string
    Age    int
    Gender string
}

func (p Person) Say(msg string) {
    fmt.Println("hello, ", msg)
}

func (p Person) PrintInfo() {
    fmt.Printf("Name: %s, Age: %d, Gender: %s", p.Name, p.Age, p.Gender)
}
func main() {
    p1 := Person{"bill", 16, "Male"}
    GetMessage(p1)
}

//獲取input的信息  在這個(gè)函數(shù)中 輸入是空接口
//代表我們并不知道input的原始類型是什么 取決于函數(shù)調(diào)用的時(shí)候摻進(jìn)來什么參數(shù)
func GetMessage(input interface{}) {
    getType := reflect.TypeOf(input)
    fmt.Println("輸入數(shù)據(jù)的類型是: ", getType.Name())
    fmt.Println("輸入數(shù)據(jù)的種類是: ", getType.Kind())

    getValue := reflect.ValueOf(input)
    fmt.Println("all fields are: ", getValue)

    //獲取字段
    for i := 0; i < getType.NumField(); i++ {
        field := getType.Field(i)
        value := getValue.Field(i).Interface()
        fmt.Printf("字段名稱: %s, 字段類型: %s, 字段值: %v\n ", field.Name, field.Type, value)
    }

    //獲取方法
    for i := 0; i < getType.NumMethod(); i++ {
        method := getType.Method(i)
        fmt.Printf("方法名稱: %s, 方法類型: %v\n", method.Name, method.Type)
    }
}

運(yùn)行結(jié)果是:

輸入數(shù)據(jù)的類型是:  Person
輸入數(shù)據(jù)的種類是:  struct
all fields are:  {bill 16 Male}
字段名稱: Name, 字段類型: string, 字段值: bill
字段名稱: Age, 字段類型: int, 字段值: 16
字段名稱: Gender, 字段類型: string, 字段值: Male
方法名稱: PrintInfo, 方法類型: func(main.Person)
方法名稱: Say, 方法類型: func(main.Person, string)

以上就是Golang學(xué)習(xí)之反射機(jī)制的用法詳解的詳細(xì)內(nèi)容,更多關(guān)于Golang反射機(jī)制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go實(shí)現(xiàn)map轉(zhuǎn)json的示例詳解

    Go實(shí)現(xiàn)map轉(zhuǎn)json的示例詳解

    這篇文章主要為大家詳細(xì)介紹了如何利用Go語言實(shí)現(xiàn)map轉(zhuǎn)json的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-09-09
  • Golang 統(tǒng)計(jì)字符串字?jǐn)?shù)的方法示例

    Golang 統(tǒng)計(jì)字符串字?jǐn)?shù)的方法示例

    本篇文章主要介紹了Golang 統(tǒng)計(jì)字符串字?jǐn)?shù)的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05
  • Golang中的參數(shù)傳遞示例詳解

    Golang中的參數(shù)傳遞示例詳解

    參數(shù)傳遞是指在程序的傳遞過程中,實(shí)際參數(shù)就會(huì)將參數(shù)值傳遞給相應(yīng)的形式參數(shù),然后在函數(shù)中實(shí)現(xiàn)對(duì)數(shù)據(jù)處理和返回的過程,下面這篇文章主要給大家介紹了關(guān)于Golang中參數(shù)傳遞的相關(guān)資料,需要的朋友可以參考下。
    2017-09-09
  • Golang分布式鎖詳細(xì)介紹

    Golang分布式鎖詳細(xì)介紹

    分布式鎖是控制分布式系統(tǒng)之間同步訪問共享資源的一種方式。如果不同的系統(tǒng)或是同一個(gè)系統(tǒng)的不同主機(jī)之間共享了一個(gè)或一組資源,那么訪問這些資源時(shí),需要通過一些互斥手段來防止彼此之間的干擾以保證一致性,在這種情況下,就需要使用分布式鎖了
    2022-10-10
  • Golang優(yōu)雅關(guān)閉channel的方法示例

    Golang優(yōu)雅關(guān)閉channel的方法示例

    Goroutine和channel是Go在“并發(fā)”方面兩個(gè)核心feature,下面這篇文章主要給大家介紹了關(guān)于Golang如何優(yōu)雅關(guān)閉channel的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考解決,下面來一起看看吧。
    2017-11-11
  • 淺談golang slice 切片原理

    淺談golang slice 切片原理

    這篇文章主要介紹了淺談golang slice 切片原理,詳細(xì)的介紹了golang slice 切片的概念和原理,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-11-11
  • go語言反射的基礎(chǔ)教程示例

    go語言反射的基礎(chǔ)教程示例

    這篇文章主要為大家介紹了go語言反射的基礎(chǔ)教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • Go語言中實(shí)現(xiàn)Unix風(fēng)格的進(jìn)程管道方法實(shí)例

    Go語言中實(shí)現(xiàn)Unix風(fēng)格的進(jìn)程管道方法實(shí)例

    這篇文章主要為大家介紹了Go語言中實(shí)現(xiàn)Unix風(fēng)格的進(jìn)程管道方法實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Go時(shí)間格式化的實(shí)現(xiàn)

    Go時(shí)間格式化的實(shí)現(xiàn)

    本文主要介紹了Go時(shí)間格式化的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Golang Printf,Sprintf,Fprintf 格式化詳解

    Golang Printf,Sprintf,Fprintf 格式化詳解

    這篇文章主要介紹了Golang Printf,Sprintf,Fprintf 格式化詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03

最新評(píng)論