反射机制主要由 reflect 包提供支持。通过反射,我们可以在运行时动态地获取和设置一个变量的值、类型和属性,而不需要在编码时就确定这些信息。
使用 reflect 包获取一个变量的类型和值
由于反射机制会带来一些性能上的开销,因此在性能敏感的场景中应该谨慎使用。
1
2
3
4
5
6
7
8
9
10
11
12
| package main
import (
"fmt"
"reflect"
)
func main() {
var x float64 = 3.14
fmt.Println("type:", reflect.TypeOf(x))
fmt.Println("value:", reflect.ValueOf(x).Float())
}
|
better to use reflect for Struct
通过反射获取结构体的类型信息、字段信息和方法信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| package main
import (
"fmt"
"reflect"
)
type Person struct {
Name string
Age int
}
func main() {
p := Person{"John", 30}
// 获取结构体类型
t := reflect.TypeOf(p)
fmt.Println("Type:", t)
// 遍历结构体字段
for i := 0; i < t.NumField(); i++ {
f := t.Field(i) // struct的Field属性仍然是Type 的一部分
fmt.Printf("Field %d: %s %s\n", i+1, f.Name, f.Type)
}
}
// Type: main.Person
// Field 1: Name string
// Field 2: Age int
|
反射机制还可以用于动态修改结构体的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| package main
import (
"fmt"
"reflect"
)
type Person struct {
Name string
Age int
}
func main() {
p := Person{"John", 30}
//调用 Elem 方法获取指向结构体变量的指针
v := reflect.ValueOf(&p).Elem()
// 通过 FieldByName 方法获取结构体的 Name 和 Age 字段
v.FieldByName("Name").SetString("Tom")
//分别调用 SetString 和 SetInt 方法修改字段的值
v.FieldByName("Age").SetInt(35)
fmt.Println(p) // 输出: {Tom 35}
}
|