go语言之反射

定义

反射是指,计算机程序在运行时,可以访问、检测和修改他本身状态或行为的一种能力。用比喻来说,反射就是程序在运行时能够“观察”并且修改自己的行为。

在 reflect 包中定义了一个接口和一个结构体,即reflect.Type接口和 reflect.Value结构体。

TypeOf()函数用来提取一个接口中值的类型信息。由于它的输入参数是一个空的 interface{},所以在调用此函数时,实参会先转化为 interface{}类型。这样,实参的类型信息、方法集、值信息都存储到 interface{} 变量里了。 ValueOf() 函数返回一个结构体变量,包含类型信息及实际值。

image

反射的三大法则

  • 反射可以将“接口类型变量” 转换为 “反射类型变量”;
  • 反射可以将“反射类型对象” 转换为 “接口类型变量”;
  • 如果要修改“反射类型对象”,则其值必须是“可写的”

将不可写类型转变为可写类型

1.不可写代码示例

package main

import(
	"fmt"
	"reflect"
)

func main() {
	var name string = "GO Web Program"

	v := reflect.ValueOf(name)

	fmt.Println(v) // GO Web Program
	fmt.Println("可写性为:", v.CanSet())  // 可写性为: false
}

2.将上述不可写类型转变为可写类型

在反射的Vaule对象中,有多个以单词Set开头的方法用于重新设置对应类型的值。下面罗列了一些常用的方法的定义:
func (v Vaule) SetBool(x bool)
func (v Vaule) SetBytes(x []byte)
func (v Vaule) SetFloat(x float64)
func (v Vaule) SetInt(x int64)
func (v Vaule) SetString(x string)

package main

import(
	"fmt"
	"reflect"
)

func main() {
	var name string = "GO Web Program"
	fmt.Println("真实 name 的原始值为:", name)               // 真实 name 的原始值为: GO Web Program

	v1 := reflect.ValueOf(&name)
	v2 := v1.Elem()

	fmt.Println("可写性为:", v2.CanSet())                // 可写性为: true
	
	v2.SetString("GO Web Proggam222") 
	           					
	fmt.Println("通过反射对象进行更新后,真实 name 变为:", name)   // 通过反射对象进行更新后,真实 name 变为: GO Web Proggam222

}

3.要使反射对象具备可写性,两个要点如下:

  • 创建反射对象时传入变量的是指针
  • 使用Elem()方法返回指针指向的数据
posted @ 2021-07-29 19:49  zhanghuiyan  阅读(33)  评论(0)    收藏  举报