golang 反射

参考:https://blog.csdn.net/u011957758/article/details/81193806

Golang反射

Golang提供了一种机制,在编译时不知道类型的情况下,可更新变量、运行时查看值、调用方法以及直接对他们的布局进行操作的机制,称为反射。

为什么需要反射

打个比方,有时候我们需要一个函数可以处理各种类型的值。在不知道类型的情况下,你可能会这么写。

1
2
3
4
5
6
7
8
9
10
11
// 代码
switch value := value.(type) {
case string:
// ...一些操作
case int:
// ...一些操作
case cbsStruct: // 自定义的结构体
// ...一些操作

// ...
}

有没发现什么问题?
这边存在一个问题:类型很多,这个函数会写的非常长,而且还可能存在自定的类型,也就是说这个判断日后可能还要一直改,因为无法知道未知值到底属于什么类型。

无法透视一个未知类型的时候,以上代码其实不是很合理,这时候就需要有反射来帮忙你处理,反射使用TypeOf和ValueOf函数从接口中获取目标对象的信息,轻松完成目的

reflect

他提供了两种类型来进行访问接口变量的内容:1.reflect.ValueOf(),2.reflect.TypeOf()

1
2
3
4
5
6
7
var serverName = "web服务器"

fmt.Println(serverName)

reflectType := reflect.TypeOf(serverName)
reflectValue := reflect.ValueOf(serverName)
fmt.Println(reflectType,reflectValue)

输出结果为:

1
string web服务器

Go语言中反射中数组、切片、Map、指针等类型的变量,它们的.Name()都是返回为空。

结构体反射

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

package main

import (
"fmt"
"reflect"
)

type student struct {
Name string `json:"name" ini:"s_name"`
Score int `json:"score" ini:"s_score"`
}


func main(){
stu1 := student{
"roddy",
90,
}

//通过反射获取结构体中的所有字段信息

t:=reflect.TypeOf(stu1)
fmt.Println(t.Name(),t.Kind())

//遍历结构体变量的所有字段
for i:=0;i<t.NumField();i++{
fileObj := t.Field(i)
//fmt.Println(fileObj.Name,fileObj.PkgPath,fileObj.Tag,fileObj.Type)

fmt.Println(fileObj.Tag.Get("json"),fileObj.Tag.Get("ini"))

}


//根据名字去获取结构体字段

filedObj2,ok :=t.FieldByName("Score")
if ok{
fmt.Println(filedObj2.Tag.Get("json"))

}


}