Go_反射

反射

反射:主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。
go语言提供了一种在运行时更新变量和检查它们的值、调用它们的方法,但是在编译时并不知道这些变量的具体类型,这称为反射机制。
1.反射作用
1.1 在编写不定传参类型函数的时候,或传入类型过多时需要反射
type User struct {
  gorm.Model
  Name         string
  Age          sql.NullInt64
  Birthday     *time.Time
  Email        string  `gorm:"type:varchar(100);unique_index"`
  Role         string  `gorm:"size:255"` // set field size to 255
  MemberNumber *string `gorm:"unique;not null"` // set member number to unique and not null
  Num          int     `gorm:"AUTO_INCREMENT"` // set num to auto incrementable
  Address      string  `gorm:"index:addr"` // create index with name `addr` for address
  IgnoreMe     int     `gorm:"-"` // ignore this field
}

var users []User
db.Find(&users)
2.不确定调用哪个函数,需要根据某些条件来动态执行需要反射
func bridge(funcPtr interface{}, args ...interface{})

第一个参数funcPtr以接口的形式传入函数指针,函数参数args以可变参数的形式传入,bridge函数中可以用反射来动态执行funcPtr函数。

2.反射三定律
2.1 反射可以将“接口类型变量”转换为“反射类型对象”。

允许程序在运行时访问接口内的数据。首先介绍一下reflect包里的两个方法reflect.Value和reflect.Type

	package main

	import (
		"fmt"
		"reflect"
	)
	
	func main() {
		var Num float64 = 3.14
	
		v := reflect.ValueOf(Num)
		t := reflect.TypeOf(Num)
	
		fmt.Println("Reflect : Num.Value = ", v)
		fmt.Println("Reflect : Num.Type  = ", t)
	}
	
	//输出结果
	Reflect : Num.Value =  3.14
	Reflect : Num.Type  =  float64
2.2 反射可以将“反射类型对象”转换为“接口类型变量”。
package main
import (
    "fmt"
    "reflect"
)
func main() {
    var Num = 3.14
    v := reflect.ValueOf(Num)
    t := reflect.TypeOf(Num)
    fmt.Println(v)
    fmt.Println(t)

    origin := v.Interface().(float64)
    fmt.Println(origin)
}
//输出结果
3.14
float64
3.14
2.3 如果要修改“反射类型对象”,其值必须是“可写的”。
package main
import (
    "reflect"
)
func main() {
        var Num float64 = 3.14
        v := reflect.ValueOf(Num)
        v.SetFloat(6.18)
}

//出现panic 因为反射对象v包含的是副本值,所以无法修改。我们可以通过CanSet函数来判断反射对象是否可以修改
 fmt.Println("v的可写性:", v.CanSet())
3.反射实践
//通过反射修改内容
var f float64 = 3.41
fmt.Println(f)
p := reflect.ValueOf(&f)
v := p.Elem() //方法获取这个指针指向的元素类型,等效于对指针类型变量做了一个*操作
v.SetFloat(6.18)
fmt.Println(f)

//通过反射调用方法
package main

import (
        "fmt"
        "reflect"
)

func hello() {
  fmt.Println("Hello world!")
}

func main() {
  hl := hello
  fv := reflect.ValueOf(hl)
  fv.Call(nil)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值