欧美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語(yǔ)言轉(zhuǎn)換所有字符串為大寫或者小寫的方法

    Go語(yǔ)言轉(zhuǎn)換所有字符串為大寫或者小寫的方法

    這篇文章主要介紹了Go語(yǔ)言轉(zhuǎn)換所有字符串為大寫或者小寫的方法,實(shí)例分析了ToLower和ToUpper函數(shù)的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • 一文詳解Golang中的匿名變量

    一文詳解Golang中的匿名變量

    匿名變量是一種特殊類型的變量,可以簡(jiǎn)化代碼并提高可讀性,本文將為大家詳細(xì)介紹一下golang中匿名變量的定義、特性和使用方法,需要的可以參考下
    2023-09-09
  • 使用Golang實(shí)現(xiàn)對(duì)網(wǎng)絡(luò)數(shù)據(jù)包的捕獲與分析

    使用Golang實(shí)現(xiàn)對(duì)網(wǎng)絡(luò)數(shù)據(jù)包的捕獲與分析

    在網(wǎng)絡(luò)通信中,網(wǎng)絡(luò)數(shù)據(jù)包是信息傳遞的基本單位,抓包是一種監(jiān)控和分析網(wǎng)絡(luò)流量的方法,用于獲取網(wǎng)絡(luò)數(shù)據(jù)包并對(duì)其進(jìn)行分析,本文將介紹如何使用Golang實(shí)現(xiàn)抓包功能,包括網(wǎng)絡(luò)數(shù)據(jù)包捕獲和數(shù)據(jù)包分析,需要的朋友可以參考下
    2023-11-11
  • golang中命令行庫(kù)cobra的使用方法示例

    golang中命令行庫(kù)cobra的使用方法示例

    這篇文章主要給大家介紹了關(guān)于golang中命令行庫(kù)cobra的使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • 詳解Go語(yǔ)言各種常見類型的默認(rèn)值和判空方法

    詳解Go語(yǔ)言各種常見類型的默認(rèn)值和判空方法

    本文主要介紹了詳解Go語(yǔ)言各種常見類型的默認(rèn)值和判空方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 最新評(píng)論