Go語言通過reflect包實(shí)現(xiàn)反射,可動(dòng)態(tài)獲取類型和值。1. 使用reflect.TypeOf和ValueOf獲取變量的類型與值,Kind返回底層數(shù)據(jù)結(jié)構(gòu);2. 遍歷結(jié)構(gòu)體字段需傳入指針并調(diào)用Elem(),結(jié)合Tag信息可實(shí)現(xiàn)序列化等操作;3. 修改字段前需調(diào)用CanSet()判斷可設(shè)置性,僅當(dāng)值可尋址時(shí)才能修改;4. 通過MethodByName查找方法并用Call調(diào)用,參數(shù)以[]reflect.Value傳遞。這些機(jī)制廣泛應(yīng)用于通用庫、ORM和序列化場景。
Go語言的反射機(jī)制通過reflect
包實(shí)現(xiàn),能夠在運(yùn)行時(shí)動(dòng)態(tài)獲取變量的類型和值,并進(jìn)行操作。反射在編寫通用庫、序列化、ORM等場景中非常有用。以下是Go反射的基礎(chǔ)語法與實(shí)用示例。
使用reflect.TypeOf
獲取變量的類型,reflect.ValueOf
獲取其值。
package main import ( "fmt" "reflect" ) func main() { var x int = 42 t := reflect.TypeOf(x) // 類型信息 v := reflect.ValueOf(x) // 值信息 fmt.Println("Type:", t) // int fmt.Println("Value:", v) // 42 fmt.Println("Kind:", v.Kind()) // int }
Type表示類型元數(shù)據(jù),Value表示具體值。注意Kind
返回的是底層數(shù)據(jù)結(jié)構(gòu)(如int、struct、slice等)。
反射可以遍歷結(jié)構(gòu)體字段,讀取或修改其值(需傳入指針)。
立即學(xué)習(xí)“go語言免費(fèi)學(xué)習(xí)筆記(深入)”;
type Person struct { Name string `json:"name"` Age int `json:"age"` } func inspectStruct(s interface{}) { v := reflect.ValueOf(s).Elem() t := v.Type() for i := 0; i < v.NumField(); i++ { field := v.Field(i) structField := t.Field(i) tag := structField.Tag.Get("json") fmt.Printf("Field: %s, Value: %v, Tag: %s\n", structField.Name, field.Interface(), tag) } } func main() { p := &Person{Name: "Alice", Age: 30} inspectStruct(p) }
輸出:
Field: Name, Value: Alice, Tag: name Field: Age, Value: 30, Tag: age
注意要傳入指針并調(diào)用Elem()
獲取指向的值,否則無法修改。
只有可尋址的reflect.Value
才能修改值,通常需傳入指針。
func setAge(obj interface{}, newAge int) { v := reflect.ValueOf(obj).Elem() ageField := v.FieldByName("Age") if ageField.CanSet() { ageField.SetInt(int64(newAge)) } } func main() { p := &Person{Name: "Bob", Age: 25} setAge(p, 35) fmt.Println(*p) // {Bob 35} }
CanSet()
判斷字段是否可被修改,未導(dǎo)出字段或非指針傳遞會(huì)導(dǎo)致不可設(shè)。
反射可以動(dòng)態(tài)調(diào)用結(jié)構(gòu)體的方法。
func (p Person) Greet() { fmt.Printf("Hello, I'm %s, %d years old.\n", p.Name, p.Age) } func callMethod(obj interface{}, methodName string) { v := reflect.ValueOf(obj) method := v.MethodByName(methodName) if method.IsValid() { method.Call(nil) // 無參數(shù)調(diào)用 } } func main() { p := &Person{Name: "Charlie", Age: 28} callMethod(p, "Greet") // 輸出問候語 }
Call
接收一個(gè)[]reflect.Value
作為參數(shù)列表,例如method.Call([]reflect.Value{})
。
以上就是Golang反射語法基礎(chǔ)與示例代碼的詳細(xì)內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!
每個(gè)人都需要一臺(tái)速度更快、更穩(wěn)定的 PC。隨著時(shí)間的推移,垃圾文件、舊注冊表數(shù)據(jù)和不必要的后臺(tái)進(jìn)程會(huì)占用資源并降低性能。幸運(yùn)的是,許多工具可以讓 Windows 保持平穩(wěn)運(yùn)行。
微信掃碼
關(guān)注PHP中文網(wǎng)服務(wù)號(hào)
QQ掃碼
加入技術(shù)交流群
Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號(hào)