Reflect反射
尚硅谷Golang課
reflect反射
func reflectTest01(b interface{}) {
//通過反射獲取傳入的各種訊息
//先拿reflect.Type
rType := reflect.TypeOf(b)
fmt.Println("rType=", rType)
rVal := reflect.ValueOf(b)
fmt.Println("rVal=", rVal)
// n1:=10+rVal //rVal他看起來是int但其實是type reflect.Value
n1 := 10 + rVal.Int() //用.Int()轉換後就可以了
// n3 := rVal.Float()//像這樣也不行的,一定要確認類型
fmt.Println("n1=", n1)
// fmt.Println("n3=", n3)
//把rVal轉回interface{}
iV := rVal.Interface()
n2 := iV.(int)
fmt.Println("n2=", n2)
}
func reflectTest02(b interface{}) {
//通過反射獲取傳入的各種訊息
//先拿reflect.Type
rType := reflect.TypeOf(b)
fmt.Println("rType=", rType)
rVal := reflect.ValueOf(b)
fmt.Println("rVal=", rVal)
//把rVal轉回interface{}
iV := rVal.Interface()
//斷言回來
n2, ok := iV.(Student)
if !ok {
fmt.Println("從interface{}轉換回Student失敗")
}
fmt.Println("n2=", n2)
fmt.Println("n2.Name=", n2.Name)
//獲取變量對應的kind,可以從Type也能從val拿。
//比如這個type是包名.Student,kind是stuct,可以說定義上kind包含type
fmt.Println("kind=", rType.Kind())
fmt.Println("kind=", rVal.Kind())
}
type Student struct {
Name string
Age int
}
func main() {
var num int = 100
reflectTest01(num)
fmt.Println("===============================")
stu := Student{
Name: "tom",
Age: 20,
}
reflectTest02(stu)
}
修改變量
func reflect01(b interface{}) {
rVal := reflect.ValueOf(b)
fmt.Println("rVal=", rVal)
rType := reflect.TypeOf(b)
fmt.Println("rType=", rType)
iV := rVal.Interface()
vNew, ok := iV.(float64)
if ok {
fmt.Println("轉換成功 vNew=", vNew)
} else {
fmt.Println("err")
}
}
func main() {
var v float64 = 1.2
reflect01(v)
// var str string = "tom" //錯誤示範
// fs := reflect.ValueOf(str)
// fs.SetString("jack")
// fmt.Println(str)
var str string = "tom"
fs := reflect.ValueOf(&str)
fs.Elem().SetString("jack")
fmt.Println(str)
}
實踐
type Monster struct {
Name string `json:"name"`
Age int `json:"age"`
Score float64
}
//方法打印m值
func (m Monster) Print() {
fmt.Println(m)
}
//方法 求2和
func (m Monster) GetSum(n1, n2 int) int {
return n1 + n2
}
//方法 接收4值給Monster
func (m Monster) Set(n string, a int, s float64) {
m.Name = n
m.Age = a
m.Score = s
}
//反射實例
func TestStruct(a interface{}) {
typ := reflect.TypeOf(a)
val := reflect.ValueOf(a)
kd := val.Kind()
if kd != reflect.Struct {
fmt.Println("傳入的不是結構體")
return
}
//獲取該結構有幾字段
num := val.NumField()
fmt.Println("struct有幾個字段=", num)
//遍歷所有字段
for i := 0; i < num; i++ {
fmt.Printf("Field%d 值為%v\n", i, val.Field(i))
//獲取struct標籤
tagVal := typ.Field(i).Tag.Get("json")
if tagVal != "" {
fmt.Printf("Field%d tag為%v\n", i, tagVal)
}
}
//獲取結構體有幾個方法
numOfMethod := val.NumMethod()
fmt.Println("方法有", numOfMethod)
//調用第[]個方法且call調用他(傳入參數值)
//但他這個是方法的首字(asc碼)當排序的 我們的方法是G P S開頭 (1)=第2個
val.Method(1).Call(nil)
//試著調用getsum 他call傳入的是要[]reflect.Value
var params []reflect.Value
params = append(params, reflect.ValueOf(10))
params = append(params, reflect.ValueOf(20))
res := val.MethodByName("GetSum").Call(params)
fmt.Println("res=", res[0].Int())
}
func main() {
var a Monster = Monster{
Name: "牛梅王",
Age: 500,
Score: 87,
}
TestStruct(a)
}
上次修改於 2021-08-01
此篇文章的評論功能已經停用。