反射是程序可以检查其自身结构的一种能力,在Golang中,反射包提供了运行时检查变量类型和值的能力。
以下是一些使用Golang反射包的常见方法:
- TypeOf 方法:用于获取任何接口的底层类型。
package main
import (
"fmt"
"reflect"
)
func main() {
var x float64 = 3.4
fmt.Println("type:", reflect.TypeOf(x))
}
- ValueOf 方法:用于获取任何接口值的底层值。
package main
import (
"fmt"
"reflect"
)
func main() {
var x float64 = 3.4
fmt.Println("value:", reflect.ValueOf(x))
}
- CanSet 方法:用于检查变量是否可以被设置(即是否可以修改)。
package main
import (
"fmt"
"reflect"
)
func main() {
var x float64 = 3.4
v := reflect.ValueOf(x)
if v.CanSet() {
fmt.Println("can set")
} else {
fmt.Println("can't set")
}
}
- SetXXX 方法:用于修改反射得到的值,其中 XXX 是具体的数据类型。
package main
import (
"fmt"
"reflect"
)
func main() {
var x float64 = 3.4
v := reflect.ValueOf(x)
v = reflect.ValueOf(&x)
if v.CanSet() {
reflect.ValueOf(&x).Elem().SetFloat(4.5)
fmt.Println(x)
}
}
- Kind 方法:用于获取变量的类型(例如,它是一种结构体,slice等)。
package main
import (
"fmt"
"reflect"
)
func main() {
var x float64 = 3.4
k := reflect.ValueOf(x).Kind()
fmt.Println("kind:", k)
}
- Interface 方法:用于将反射对象转换为接口。
package main
import (
"fmt"
"reflect"
)
func main() {
var x float64 = 3.4
v := reflect.ValueOf(x)
if v.CanInterface() {
fmt.Println("interface:", v.Interface())
}
}
- NumField 和 Field 方法:用于获取结构体的字段数量和对应的字段值。
package main
import (
"fmt"
"reflect"
)
type T struct {
A int
B string
}
func main() {
t := T{23, "skidoo"}
s := reflect.ValueOf(&t).Elem()
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
fmt.Printf("field %d: %v\n", i, f)
}
}
- NumMethod 和 Method 方法:用于获取结构体的方法数量和对应的方法值。
package main
import (
"fmt"
"reflect"
)
type T struct{}
func (t T) F() { fmt.Println("F") }
func main() {
t := T{}
s := reflect.ValueOf(&t).Elem()
for i := 0; i < s.NumMethod(); i++ {
m := s.Method(i)
fmt.Printf("method %d: