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

深入了解Golang中reflect反射的使用

 更新時(shí)間:2023年05月11日 11:42:28   作者:未來(lái)誰(shuí)可知  
這篇文章主要介紹了深入了解Golang中reflect反射的使用,Go語(yǔ)言中的反射是一種機(jī)制,可以在運(yùn)行時(shí)動(dòng)態(tài)地獲取類型信息和操作對(duì)象,以及調(diào)用對(duì)象的方法和屬性等,需要詳細(xì)了解可以參考下文

1. 介紹

在反射的世界里,我們擁有了獲取一個(gè)對(duì)象的類型,屬性及方法的能力。

在 Go 反射的世界里,有兩種類型非常重要,是整個(gè)反射的核心,在學(xué)習(xí) reflect 包的使用時(shí),先得學(xué)習(xí)下這兩種類型:

  • reflect.Type
  • reflect.Value

2. 方法示例

2.1 通過(guò)反射獲取對(duì)象的鍵(類型)和值

package main
import (
   "fmt"
   "reflect"
)
//
func reflectNum(arg interface{})  {
   fmt.Println("type:",reflect.TypeOf(arg))
   fmt.Println("value : ",reflect.ValueOf(arg))
}
func main() {
   reflectNum(1.1234)
}

type: float64
value : 1.1234

注意,Go 中所有對(duì)象都是鍵+值組成的,含有這種特性的對(duì)象都是可以用 Type + Value 進(jìn)行抽象的,這就是萬(wàn)能對(duì)象

2.2 反射對(duì)象的類型和屬性

package main
import (
   "fmt"
   "reflect"
)
type User struct {
   Id int
   Name string
   Age int
}
func (this User) Call()  {
   fmt.Println("user is called ..")
   fmt.Printf("#{this}\n")
}
func main() {
   user := User{1,"Aceld",18}
   //傳入 user 對(duì)象
   DoFiledAndMethod(user)
}
//接收萬(wàn)能對(duì)象 用反射解析
func DoFiledAndMethod(input interface{})  {
   //反射獲取類的類型
   inputType := reflect.TypeOf(input)
   fmt.Println("inputType is :", inputType.Name() )
  // inputType is : User
   inputValue := reflect.ValueOf(input)
   fmt.Println("inputValue is :", inputValue)
  //inputValue is : {1 Aceld 18}
   //反射獲取類的屬性
   for i := 0; i < inputType.NumField(); i++ {
      field := inputType.Field(i)
      value := inputValue.Field(i).Interface()
      fmt.Printf("%s : %v = %v\n",field.Name,field.Type,value)
      //Id : int = 1
      //Name : string = Aceld
      //Age : int = 18
   }
   //反射調(diào)用方法
   for i := 0; i < inputType.NumMethod(); i++ {
      m := inputType.Method(i)
      //%s 輸出字符串表示(string類型或[]byte)
      //%v  相應(yīng)值的默認(rèn)格式。
      fmt.Printf("%s:%v\n",m.Name,m.Type)
     //Call:func(main.User)
   }
}

3. 反射對(duì)Json的操作

3.1 反射與Json屬性解析

在結(jié)構(gòu)體屬性中 我們可以通過(guò)加 tag 以供其他程序的解析與識(shí)別

package main
import (
   "fmt"
   "reflect"
)
type resume struct {
   // ':'前后不加空格  ` != '
   Name string `info:"name"  doc:"我的名字" `
   Sex string `info:"sex" `
}
func findTag(str interface{})  {
   // Elem returns a type's element type.
   t := reflect.TypeOf(str).Elem()
  //遍歷接收對(duì)象的屬性
   for i := 0; i < t.NumField(); i++ {
      taginfo := t.Field(i).Tag.Get("info")
      tagdoc := t.Field(i).Tag.Get("doc")
      fmt.Println("info:",taginfo,"doc:",tagdoc)
   }
}
func main() {
   var re resume
   findTag(&re)
}
輸出:
  info: name doc: 我的名字
  info: sex doc:

3.2 Json包的序列化與反序列化

go 的 json 工具要想解析 需要你在字段上添加 json tag

package main
import (
   "encoding/json"
   "fmt"
)
// 全部添加 json 的 tag
type Movie struct {
   Title string `json:"title"`
   Year int `json:"year"`
   Price int `json:"rmb"`
   Actors []string `json:"actors"`
}
func main() {
   movie := Movie{"喜劇之王", 2000, 10, []string{"zhouxingchi", "wumengda"}}
   // 序列化
   jsonStr, err := json.Marshal(movie)
   if err != nil {
      fmt.Println("json marshal error",err)
      return
   }
   fmt.Printf("jsonStr = %s\n",jsonStr)
   //反序列化
   m := Movie{}
   err = json.Unmarshal(jsonStr, &m)
   if err != nil {
      fmt.Println("json ummarshal error", err)
      return
   }
   fmt.Printf("%v\n",m)
}

4. 實(shí)戰(zhàn)鞏固

4.1 需求

? 項(xiàng)目經(jīng)常會(huì)在啟動(dòng)的時(shí)候會(huì)加一些環(huán)境變量參數(shù),隨著啟動(dòng)而觸發(fā)作用加載到項(xiàng)目中,現(xiàn)如今在。利用os包設(shè)置好環(huán)境變量,利用反射實(shí)現(xiàn)項(xiàng)目啟動(dòng)時(shí)運(yùn)行時(shí)加載進(jìn)環(huán)境!

環(huán)境變量KeyCONFIG_SERVER_NAMECONFIG_SERVER_IPCONFIG_SERVER_URL

4.2 代碼實(shí)現(xiàn)

package main
import (
	"fmt"
	"os"
	"reflect"
	"strings"
)
type Config struct {
	Name    string `json:"server-name"`
	IP      string `json:"server-ip"`
	URL     string `json:"server-url"`
	Timeout string `json:"timeout"`
}
func readConfig() *Config {
	// read from xxx.json,省略
	config := Config{}
	// 1. 拿到config的反射類型
	typ := reflect.TypeOf(config)
	// 2. 拿到config的反射值對(duì)象
	value := reflect.Indirect(reflect.ValueOf(&config))
	// 3. 遍歷每個(gè)字段
	for i := 0; i < typ.NumField(); i++ {
		// 3.1 拿到反射的config的第i個(gè)字段
		f := typ.Field(i)
		// 3.2 拿到賦值了json的字段tag
		if v, ok := f.Tag.Lookup("json"); ok {
			// 3.3 拼接系統(tǒng)環(huán)境變量Key
			key := fmt.Sprintf("CONFIG_%s", strings.ReplaceAll(strings.ToUpper(v), "-", "_"))
			// 3.4 從系統(tǒng)中讀取環(huán)境變量對(duì)應(yīng)的值
			if env, exist := os.LookupEnv(key); exist {
				// 3.5 將值設(shè)置到給定名稱的字段上
				value.FieldByName(f.Name).Set(reflect.ValueOf(env))
			}
		}
	}
	return &config
}
func main() {
	os.Setenv("CONFIG_SERVER_NAME", "global_server")
	os.Setenv("CONFIG_SERVER_IP", "10.0.0.1")
	os.Setenv("CONFIG_SERVER_URL", "geektutu.com")
	c := readConfig()
	fmt.Printf("%+v", c)
}

到此這篇關(guān)于深入了解Golang中reflect反射的使用的文章就介紹到這了,更多相關(guān)Go reflect反射內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go項(xiàng)目與Docker結(jié)合實(shí)現(xiàn)高效部署深入探究

    Go項(xiàng)目與Docker結(jié)合實(shí)現(xiàn)高效部署深入探究

    在現(xiàn)代軟件開(kāi)發(fā)中,使用Docker部署應(yīng)用程序已經(jīng)成為一種標(biāo)準(zhǔn)實(shí)踐,本文將深入探討如何將Go項(xiàng)目與Docker結(jié)合,實(shí)現(xiàn)高效、可靠的部署過(guò)程,通過(guò)詳細(xì)的步驟和豐富的示例,你將能夠迅速掌握這一流程
    2023-12-12
  • Go高級(jí)特性探究之HTTP錯(cuò)誤處理詳解

    Go高級(jí)特性探究之HTTP錯(cuò)誤處理詳解

    在Web應(yīng)用程序中,HTTP錯(cuò)誤處理是非常重要的,它關(guān)系到Web應(yīng)用程序的穩(wěn)定性和可靠性,本文介紹如何在Go項(xiàng)目中處理HTTP錯(cuò)誤,并提供相應(yīng)的解決方案和實(shí)踐經(jīng)驗(yàn),希望對(duì)Go語(yǔ)言Web應(yīng)用程序的開(kāi)發(fā)者有所幫助
    2023-06-06
  • golang 實(shí)現(xiàn)比特幣內(nèi)核之處理橢圓曲線中的天文數(shù)字

    golang 實(shí)現(xiàn)比特幣內(nèi)核之處理橢圓曲線中的天文數(shù)字

    比特幣密碼學(xué)中涉及到的大數(shù)運(yùn)算超出常規(guī)整數(shù)范圍,需使用golang的big包進(jìn)行處理,通過(guò)使用big.Int類型,能有效避免整數(shù)溢出,并保持邏輯正確性,測(cè)試展示了在不同質(zhì)數(shù)模下的運(yùn)算結(jié)果,驗(yàn)證了邏輯的準(zhǔn)確性,此外,探討了費(fèi)馬小定理在有限字段除法運(yùn)算中的應(yīng)用
    2024-11-11
  • go-zero?組件布隆過(guò)濾器使用示例詳解

    go-zero?組件布隆過(guò)濾器使用示例詳解

    這篇文章主要為大家介紹了go-zero組件介紹之布隆過(guò)濾器使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • Go語(yǔ)言利用ffmpeg轉(zhuǎn)hls實(shí)現(xiàn)簡(jiǎn)單視頻直播

    Go語(yǔ)言利用ffmpeg轉(zhuǎn)hls實(shí)現(xiàn)簡(jiǎn)單視頻直播

    這篇文章主要為大家介紹了Go語(yǔ)言利用ffmpeg轉(zhuǎn)hls實(shí)現(xiàn)簡(jiǎn)單視頻直播,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • Golang中的int類型和uint類型到底有多大?

    Golang中的int類型和uint類型到底有多大?

    int和uint類型在我們?nèi)粘i_(kāi)發(fā)中經(jīng)常會(huì)用到,但有個(gè)疑問(wèn)就是這兩個(gè)類型有多大,通過(guò)各種嘗試最終得到了答案,所以下面這篇文章主要給大家介紹了關(guān)于Golang中的int類型和uint類型到底有多大的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。
    2017-12-12
  • Go語(yǔ)言框架Beego項(xiàng)目搭建的方法步驟

    Go語(yǔ)言框架Beego項(xiàng)目搭建的方法步驟

    這篇文章主要介紹了Go語(yǔ)言框架Beego項(xiàng)目搭建的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Gin golang web開(kāi)發(fā)模型綁定實(shí)現(xiàn)過(guò)程解析

    Gin golang web開(kāi)發(fā)模型綁定實(shí)現(xiàn)過(guò)程解析

    這篇文章主要介紹了Gin golang web開(kāi)發(fā)模型綁定實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Go整合ElasticSearch的示例代碼

    Go整合ElasticSearch的示例代碼

    這篇文章主要介紹了Go整合ElasticSearch的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • Go語(yǔ)言中的并發(fā)模式你了解了嗎

    Go語(yǔ)言中的并發(fā)模式你了解了嗎

    工作中查看項(xiàng)目代碼,發(fā)現(xiàn)會(huì)存在使用?GO?語(yǔ)言做并發(fā)的時(shí)候出現(xiàn)各種各樣的異常情況,實(shí)際上,出現(xiàn)上述的情況,還是因?yàn)槲覀儗?duì)于?GO?語(yǔ)言的并發(fā)模型和涉及的?GO?語(yǔ)言基礎(chǔ)不夠扎實(shí),所以本文小編就來(lái)帶大家深入了解下Go語(yǔ)言中的并發(fā)模式吧
    2023-08-08

最新評(píng)論