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

Go語言的反射reflect使用大全

 更新時間:2024年08月15日 10:52:42   作者:努力的悟空  
Go語言中reflect包提供了運行時反射的功能,本文主要介紹了Go語言的反射reflect使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

Go語言作為一個高性能的靜態(tài)語言,我們在寫函數(shù)的時候,由于go語言的特性,我們需要定義變量類型,大多情況下,變量類型是固定結(jié)構(gòu)體,這就會導(dǎo)致我們想做一個適配性較高的函數(shù)的時候,則需要將變量以及返回值用interface{}接口實現(xiàn)

一、映射的基本用法

1.獲取類型信息

使用`reflect.TypeOf()`可以獲取任何值的類型信息

var x float64 = 3.4
fmt.Println("type:", reflect.TypeOf(x))

2.獲取值

使用`reflect.ValueOf()`可以獲取reflect.Value類型表示的實際值:

var x float64 = 3.4
v := reflect.ValueOf(x)
fmt.Println("value:", v)
fmt.Println("type:", v.Type())
fmt.Println("kind:", v.Kind())

3.讀取和設(shè)置值

通過reflect可以對變量的值進行讀取和設(shè)置:

var x float64 = 3.4
p := reflect.ValueOf(&x) // 注意這里必須要傳遞x的地址
v := p.Elem()
v.SetFloat(7.1)

4.使用Kind來區(qū)分類型

`reflect.Kind`可以用來區(qū)分基本類型:

v := reflect.ValueOf(x)
if v.Kind() == reflect.Float64 {
    // x是float64類型
}

5.操作結(jié)構(gòu)體

可以通過`reflect`包來動態(tài)地讀取和設(shè)置結(jié)構(gòu)體的字段,甚至可以調(diào)用方法:

type MyStruct struct {
    Field1 int
    Field2 string
}

s := MyStruct{Field1: 10, Field2: "Hello"}
v := reflect.ValueOf(s)
typeOfS := v.Type()

for i := 0; i < v.NumField(); i++ {
    field := v.Field(i)
    fmt.Printf("%d: %s %s = %v
", i, typeOfS.Field(i).Name, field.Type(), field.Interface())
}

6.創(chuàng)建新實例

type MyStruct struct {
    Field1 int
}

var msType reflect.Type = reflect.TypeOf(MyStruct{})
msValue := reflect.New(msType).Elem()
msValue.Field(0).SetInt(10)

7.調(diào)用方法

//動態(tài)調(diào)用方法

v := reflect.ValueOf(s)
m := v.MethodByName("MethodName")
args := []reflect.Value{reflect.ValueOf(arg1), reflect.ValueOf(arg2)}
result := m.Call(args)

8.調(diào)用方法

對于映射、切片和數(shù)組類型,`reflect`包提供了額外的函數(shù)來動態(tài)操作它們;例如可以通過`reflect.Append`、`reflect.MakeSlice`等創(chuàng)建和操作切片:

a := []int{1,2,3}
v := reflect.ValueOf(a)
newValue := reflect.Append(v, reflect.ValueOf(4))
fmt.Println(newValue.Interface()) // [1 2 3 4]

二、使用實例

在GIN+GROM框架中我建立了一個表模板

type TempGeo struct {
	BSM  string `gorm:"type:varchar(255);primary_key"`
	TBMJ float64
	MAC  string `gorm:"type:varchar(255)"`
	Name string `gorm:"type:varchar(255)"`
	Date string `gorm:"type:varchar(255)"`
	Geom string `gorm:"type:geometry(MultiPolygon,4326)"`
}

我寫了一個接口,想將這個表轉(zhuǎn)換為Geojson

func (uc *UserController) ShowTempGeo(c *gin.Context) {
	bsm := c.Query("bsm")
	var mytable []models.TempGeo
	DB := models.DB
	DB.Where("bsm = ?", bsm).Find(&mytable)
	data := methods.MakeGeoJSON(mytable)
	c.JSON(http.StatusOK, data)
}

其中的MakeGeoJSON函數(shù)就是使用了映射實現(xiàn)的,如果不使用映射,就會出現(xiàn)如果我重新造一個表,那么我就需要重寫一個MakeGeoJSON函數(shù)并新定義變量,這是靜態(tài)語言很麻煩的一個事情,還好go在這方面有一個映射的口子,讓我們能寫出泛用性函數(shù)。以下代碼就是將數(shù)據(jù)都通過映射實現(xiàn)。

func MakeGeoJSON(items interface{}) interface{} {
	var FeaturesList []*geojson.Feature
	FeaturesList = []*geojson.Feature{}

	var sliceValue reflect.Value
	if reflect.TypeOf(items).Kind() == reflect.Slice {
		sliceValue = reflect.ValueOf(items)
	} else {
		sliceValue = reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf(items)), 1, 1)
		sliceValue.Index(0).Set(reflect.ValueOf(items))
	}

	for i := 0; i < sliceValue.Len(); i++ {
		t := sliceValue.Index(i).Interface()
		v := reflect.ValueOf(t)
		tt := reflect.TypeOf(t)
		geomField := v.FieldByName("Geom")
		if !geomField.IsValid() {
			continue
		}
		geomStr, _ := geomField.Interface().(string)
		properties := make(map[string]interface{})
		for i := 0; i < v.NumField(); i++ {
			if tt.Field(i).Name != "Geom" {
				properties[strings.ToLower(tt.Field(i).Name)] = v.Field(i).Interface()
			}
		}
		wkbBytes, _ := hex.DecodeString(strings.Trim(geomStr, "  "))
		geom, _ := wkb.Unmarshal(wkbBytes)

		feature := geojson.NewFeature(geom)
		feature.Properties = properties
		FeaturesList = append(FeaturesList, feature)
	}
	features := geojson.NewFeatureCollection()
	features.Features = FeaturesList
	GeoJSON, _ := json.Marshal(features)
	var obj interface{}
	json.Unmarshal(GeoJSON, &obj)
	return obj
}

總結(jié)

在Go語言中,`reflect`包被用來在運行時動態(tài)地操作對象。盡管這個包非常強大,但是它通常不建議用于日常編程,因為它會使代碼更難理解和維護,同時也會減慢程序運行速度。但是當(dāng)你需要編寫通用代碼或者框架,或者需要處理未知類型的數(shù)據(jù)時,`reflect`  包就顯得非常有用。

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

相關(guān)文章

  • Go語言中io包核心接口示例詳解

    Go語言中io包核心接口示例詳解

    Go的io包提供了io.Reader和io.Writer接口,分別用于數(shù)據(jù)的輸入和輸出,下面這篇文章主要給大家介紹了關(guān)于Go語言中io包核心接口的相關(guān)資料,需要的朋友可以參考下
    2021-12-12
  • Go語言中序列化與反序列化示例詳解

    Go語言中序列化與反序列化示例詳解

    我們的數(shù)據(jù)對象要在網(wǎng)絡(luò)中傳輸或保存到文件,就需要對其編碼和解碼動作,Go語言當(dāng)然也支持所有這些編碼格式,下面這篇文章主要給大家介紹了關(guān)于Go語言中序列化與反序列化的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • Golang多模塊開發(fā)的詳細過程

    Golang多模塊開發(fā)的詳細過程

    這篇文章主要給大家介紹了關(guān)于Golang多模塊開發(fā)的詳細過程,文中通過實例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2023-02-02
  • 一文帶大家了解Go語言中的內(nèi)聯(lián)優(yōu)化

    一文帶大家了解Go語言中的內(nèi)聯(lián)優(yōu)化

    內(nèi)聯(lián)優(yōu)化是一種常見的編譯器優(yōu)化策略,通俗來講,就是把函數(shù)在它被調(diào)用的地方展開,這樣可以減少函數(shù)調(diào)用所帶來的開銷,本文主要為大家介紹了Go中內(nèi)聯(lián)優(yōu)化的具體使用,需要的可以參考下
    2023-05-05
  • 詳解Golang的GC三色標(biāo)記法

    詳解Golang的GC三色標(biāo)記法

    這篇文章主要為大家介紹了Golang的GC三色標(biāo)記法,文中有詳細的實現(xiàn)過程供大家參考,對大家的學(xué)習(xí)或工作有一定幫助,感興趣的可以跟著小編一來看看
    2023-05-05
  • GoLang使goroutine停止的五種方法實例

    GoLang使goroutine停止的五種方法實例

    goroutine是Go并行設(shè)計的核心,下面這篇文章主要給大家介紹了關(guān)于GoLang使goroutine停止的五種方法,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-07-07
  • golang中配置?sql.DB獲得更好的性能

    golang中配置?sql.DB獲得更好的性能

    這篇文章主要介紹了golang中如何配置?sql.DB獲得更好的性能,在這篇文章中,我想準(zhǔn)確解釋這些設(shè)置的作用,并展示它們可能產(chǎn)生的(積極和消極)影響,需要的朋友可以參考下
    2023-10-10
  • 解決go語言ssh客戶端密碼過期問題

    解決go語言ssh客戶端密碼過期問題

    這篇文章主要介紹了go語言ssh客戶端解決密碼過期問題,本文給大家分享了解決的方法和原理,非常不錯,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • Go語言io?pipe源碼分析詳情

    Go語言io?pipe源碼分析詳情

    這篇文章主要介紹了Go語言io?pipe源碼分析詳情,pipe是一個適配器,用于連接Reader和Writer,pipe的方法不多,新的寫法卻不少,并且結(jié)構(gòu)體分兩塊,讀寫信道和結(jié)束標(biāo)識,下面進入文章了解具體的內(nèi)容吧
    2022-02-02
  • Golang反射模塊reflect使用方式示例詳解

    Golang反射模塊reflect使用方式示例詳解

    Golang的反射功能,在很多場景都會用到,最基礎(chǔ)的莫過于rpc、orm跟json的編解碼,更復(fù)雜的可能會到做另外一門語言的虛擬機,這篇文章主要介紹了Golang反射模塊reflect使用方式探索,需要的朋友可以參考下
    2023-01-01

最新評論