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

Go語(yǔ)言的反射reflect使用大全

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

前言

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

一、映射的基本用法

1.獲取類型信息

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

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

2.獲取值

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

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可以對(duì)變量的值進(jìn)行讀取和設(shè)置:

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

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

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

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

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

可以通過`reflect`包來(lái)動(dòng)態(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)建新實(shí)例

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)用方法

//動(dòng)態(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)用方法

對(duì)于映射、切片和數(shù)組類型,`reflect`包提供了額外的函數(shù)來(lái)動(dòng)態(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]

二、使用實(shí)例

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

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)"`
}

我寫了一個(gè)接口,想將這個(gè)表轉(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ù)就是使用了映射實(shí)現(xiàn)的,如果不使用映射,就會(huì)出現(xiàn)如果我重新造一個(gè)表,那么我就需要重寫一個(gè)MakeGeoJSON函數(shù)并新定義變量,這是靜態(tài)語(yǔ)言很麻煩的一個(gè)事情,還好go在這方面有一個(gè)映射的口子,讓我們能寫出泛用性函數(shù)。以下代碼就是將數(shù)據(jù)都通過映射實(shí)現(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語(yǔ)言中,`reflect`包被用來(lái)在運(yùn)行時(shí)動(dòng)態(tài)地操作對(duì)象。盡管這個(gè)包非常強(qiáng)大,但是它通常不建議用于日常編程,因?yàn)樗鼤?huì)使代碼更難理解和維護(hù),同時(shí)也會(huì)減慢程序運(yùn)行速度。但是當(dāng)你需要編寫通用代碼或者框架,或者需要處理未知類型的數(shù)據(jù)時(shí),`reflect`  包就顯得非常有用。

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

相關(guān)文章

  • Golang初始化MySQL數(shù)據(jù)庫(kù)方法淺析

    Golang初始化MySQL數(shù)據(jù)庫(kù)方法淺析

    這篇文章主要介紹了Golang初始化MySQL數(shù)據(jù)庫(kù)的方法,數(shù)據(jù)庫(kù)的建立第一步即要初始化,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-05-05
  • Golang的select多路復(fù)用及channel使用操作

    Golang的select多路復(fù)用及channel使用操作

    這篇文章主要介紹了Golang的select多路復(fù)用及channel使用操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2020-12-12
  • 一文讓你理解go語(yǔ)言的Context

    一文讓你理解go語(yǔ)言的Context

    在Go語(yǔ)言中,Context(上下文)是一個(gè)類型,用于在程序中傳遞請(qǐng)求范圍的值、截止時(shí)間、取消信號(hào)和其他與請(qǐng)求相關(guān)的上下文信息,它在多個(gè)goroutine之間傳遞這些值,使得并發(fā)編程更加可靠和簡(jiǎn)單,本文詳細(xì)介紹go語(yǔ)言的Context,需要的朋友可以參考下
    2023-05-05
  • 一文帶你了解Go語(yǔ)言中的匿名函數(shù)

    一文帶你了解Go語(yǔ)言中的匿名函數(shù)

    無(wú)論是在Go語(yǔ)言還是其他編程語(yǔ)言中,匿名函數(shù)都扮演著重要的角色,本文將詳細(xì)介紹Go語(yǔ)言中匿名函數(shù)的概念和使用方法,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-06-06
  • go panic時(shí)如何讓函數(shù)返回?cái)?shù)據(jù)?

    go panic時(shí)如何讓函數(shù)返回?cái)?shù)據(jù)?

    今天小編就為大家分享一篇關(guān)于go panic時(shí)如何讓函數(shù)返回?cái)?shù)據(jù)?,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-04-04
  • 高效封禁:利用Go封裝功能,提升封禁操作效率

    高效封禁:利用Go封裝功能,提升封禁操作效率

    在網(wǎng)絡(luò)安全領(lǐng)域,封禁操作是一項(xiàng)重要的任務(wù),用于阻止惡意行為和保護(hù)系統(tǒng)安全,而利用Go語(yǔ)言封裝功能可以提升封禁操作的效率,Go語(yǔ)言具有高效的并發(fā)性能和簡(jiǎn)潔的語(yǔ)法,使得開發(fā)者可以快速構(gòu)建高性能的封禁系統(tǒng),
    2023-10-10
  • GO語(yǔ)言make()分配用法實(shí)例

    GO語(yǔ)言make()分配用法實(shí)例

    這篇文章主要介紹了GO語(yǔ)言make()分配用法,實(shí)例分析了make()的功能及使用技巧,需要的朋友可以參考下
    2015-02-02
  • Go外部依賴包從vendor,$GOPATH和$GOPATH/pkg/mod查找順序

    Go外部依賴包從vendor,$GOPATH和$GOPATH/pkg/mod查找順序

    這篇文章主要介紹了Go外部依賴包vendor,$GOPATH和$GOPATH/pkg/mod下查找順序,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧
    2020-12-12
  • 詳解Golang如何使用Debug庫(kù)優(yōu)化代碼

    詳解Golang如何使用Debug庫(kù)優(yōu)化代碼

    這篇文章將針對(duì)Golang的debug庫(kù)進(jìn)行全面解讀,涵蓋其核心組件、高級(jí)功能和實(shí)戰(zhàn)技巧,文中的示例代碼講解詳細(xì),有需要的小伙伴可以參考下
    2024-02-02
  • Golang錯(cuò)誤處理:異常捕捉和恢復(fù)機(jī)制

    Golang錯(cuò)誤處理:異常捕捉和恢復(fù)機(jī)制

    Golang中,異常處理是通過 defer + panic + recover 的方式來(lái)實(shí)現(xiàn)的,使用 defer 可以將清理操作注冊(cè)到函數(shù)執(zhí)行完畢后執(zhí)行,而 panic 和 recover 可以用于處理異常,通過組合使用這些功能,可以實(shí)現(xiàn)更加健壯的程序
    2024-01-01

最新評(píng)論

扬州市| 阜宁县| 忻城县| 高安市| 扎囊县| 上高县| 金寨县| 盐津县| 镇坪县| 循化| 陇川县| 武冈市| 石首市| 博客| 唐山市| 安徽省| 高邮市| 都匀市| 惠来县| 鞍山市| 石阡县| 临猗县| 无锡市| 湘潭县| 通州区| 洱源县| 北流市| 漠河县| 合江县| 南澳县| 龙陵县| 犍为县| 左云县| 日照市| 荔浦县| 三台县| 泾源县| 措勤县| 松溪县| 乐清市| 朝阳市|