Go语言反射Value详解

Go语言反射Value详解教程

Golang 中,通过 反射 的方法 reflect.TypeOf 可以获取 变量数据类型,通过反射的 reflect.ValueOf 可以获取变量的值信息。

同时,通过 reflect.ValueOf 的 Elem() 可以得到传入的变量的指针指向的具体对象。

反射获取变量值信息

语法

reflect.ValueOf(varname)

说明

使用 reflect.ValueOf 传入我们要获取的变量,可以获取该变量的值信息。

反射获取变量所指向的指针

语法

reflect.ValueOf(varname).Elem()

说明

使用 reflect.ValueOf 的 Elem() 方法传入我们要获取的变量,可以获取该变量的指针所指向的对象的信息。如果 ValueOf 传入的是值类型,那么使用 Elem 获取地址会 panic。

因此,使用 Elem() 获取地址的前提是,我们传入的 varname 是一个地址,而不是一个值类型。

案例

Go语言反射获取变量值

如果 ValueOf 传入要获取的变量,可以获取到该变量的值

package main import ( "fmt" "reflect" ) func main() { fmt.Println("嗨客网(www.haicoder.net)") var x = 1024 var str = "HaiCoder" valueX := reflect.ValueOf(x) valueStr := reflect.ValueOf(str) fmt.Println("valueX =", valueX) fmt.Println("valueStr =", valueStr) }

程序运行后,控制台输出如下:

08_golang反射Value详细信息.png

首先,我们定义了一个 int 类型 的变量 x 和一个 字符串 类型的变量 str,接着,我们使用 reflect.ValueOf 获取这两个变量的值信息。

最后,我们通过 print 打印获取的变量的值,我们发现可以通过 reflect.ValueOf 获取到变量的值。

Go语言反射获取变量地址

如果 ValueOf 传入的是值类型,那么使用 Elem 获取地址会 panic

package main import ( "fmt" "reflect" ) func main() { fmt.Println("嗨客网(www.haicoder.net)") var x = 1024 var str = "HaiCoder" valueX := reflect.ValueOf(x) valueStr := reflect.ValueOf(str) fmt.Println("valueX =", valueX) fmt.Println("valueStr =", valueStr) valueElemX := valueX.Elem() valueElemStr := valueStr.Elem() fmt.Println("valueElemX =", valueElemX) fmt.Println("valueElemStr =", valueElemStr) }

程序运行后,控制台输出如下:

09_golang反射Value详细信息.png

我们在 reflect.ValueOf(x) 方法里面传入的一个值类型的变量,接着使用 Elem() 方法获取其地址,程序报错。

Go语言反射获取变量地址

如果 ValueOf 传入的是地址,那么使用 Elem 可以获取变量的指针指向的对象

package main import ( "fmt" "reflect" ) func main() { fmt.Println("嗨客网(www.haicoder.net)") var x = 1024 var str = "HaiCoder" pValueX := reflect.ValueOf(&x) pValueStr := reflect.ValueOf(&str) fmt.Println("pvalueX =", pValueX) fmt.Println("pvalueStr =", pValueStr) pValueElemX := pValueX.Elem() pValueElemStr := pValueStr.Elem() fmt.Println("pValueElemX =", pValueElemX) fmt.Println("pValueElemStr =", pValueElemStr) }

程序运行后,控制台输出如下:

10_golang反射Value详细信息.png

我们在 reflect.ValueOf(x) 方法里面传入的一个值类型的变量的地址,接着使用 Elem() 方法获取其地址,程序不再报错。

Go语言反射获取变量地址

即使 ValueOf 传入的是引用类型,那么使用 Elem 获取地址同样会 panic

package main import ( "fmt" "reflect" ) func main() { fmt.Println("嗨客网(www.haicoder.net)") var( valInts = []int{256, 512, 1024} valStrs = []string{"HaiCoder", "Python"} ) pValueInts := reflect.ValueOf(valInts) pValueStrs := reflect.ValueOf(valStrs) fmt.Println("pValueInts =", pValueInts) fmt.Println("pValueStrs =", pValueStrs) pValueElemInts := pValueInts.Elem() pValueElemStrs := pValueStrs.Elem() fmt.Println("pValueElemInts =", pValueElemInts) fmt.Println("pValueElemStrs =", pValueElemStrs) }

程序运行后,控制台输出如下:

11_golang反射Value详细信息.png

我们在 reflect.ValueOf(x) 方法里面传入的一个引用类型的变量,接着使用 Elem() 方法获取其地址,程序报错。

Go语言反射获取变量地址

如果 ValueOf 传入的是引用类型的地址,那么使用 Elem 获取变量指向的对象成功

package main import ( "fmt" "reflect" ) func main() { fmt.Println("嗨客网(www.haicoder.net)") var( valInts = []int{256, 512, 1024} valStrs = []string{"HaiCoder", "Python"} ) pValueInts := reflect.ValueOf(&valInts) pValueStrs := reflect.ValueOf(&valStrs) fmt.Println("pValueInts =", pValueInts) fmt.Println("pValueStrs =", pValueStrs) pValueElemInts := pValueInts.Elem() pValueElemStrs := pValueStrs.Elem() fmt.Println("pValueElemInts =", pValueElemInts) fmt.Println("pValueElemStrs =", pValueElemStrs) }

程序运行后,控制台输出如下:

12_golang反射Value详细信息.png

我们在 reflect.ValueOf(x) 方法里面传入的一个引用类型的变量的地址,接着使用 Elem() 方法获取其指向的对象,程序不再报错。

Go语言反射Value详解教程总结

在 Golang 中,通过反 的方法 reflect.TypeOf 可以获取变量的数据类型,通过反射的 reflect.ValueOf 可以获取变量的值信息。

同时,通过 reflect.ValueOf 的 Elem() 可以得到传入的变量的指针指向的具体对象。Go 语言反射获取变量值信息语法:

reflect.ValueOf(varname)

Go 语言反射获取变量所指向的指针语法:

reflect.ValueOf(varname).Elem()