Go——反射规则

2023-05-16

反射规则

Value、Type和类型实例之间的相互转化如下图:
在这里插入图片描述

1、反射API

  1. 从实例到Value
    通过实例获取Value对象,直接使用reflect.ValueOf()函数。例如:
func ValueOf(i interface{}) Value
  1. 从实例到Type
    通过实例获取反射对象的Type,直接使用reflect.TypeOf()函数。例如:
func TypeOf(i interface{}) Type
  1. 从Type到Value
    Type里面只有类型信息,所以直接从一个Type接口变量里面是无法获得实例的。但可以通过该Type构建一个新实例的Value,reflect包提供了两种方法,示例如下:
//New返回的是一个Value,该Value的type为PtrTo(type),即Value的Type是指定type的指针类型
func New(type Type) Value

//Zero返回的是一个type类型的零值,注意返回的Value不能寻址,值不可改变
func Zero(type Type) Value

//如果知道一个类型值的底层存放地址,则还有一个函数是可以依据type和该地址值恢复出Value的。例如:
func NewAt(type Type, p unsafe.Pointer) Value
  1. 从Value到Type
    从反射对象Value到Type可以直接调用Value的方法,因为Value内部存放着到Type类型的指针。例如:
func (v Value)Type()Type
  1. 从Value到实例
    Value本身就包含类型和值信息,reflect提供了丰富的方法来实现从Value到实例的转换。
    例如:
//该方法最通用,用来将a11e转换为空接口,该空接口内部存放具体类型实例
//可以使用接口类型查询去还原为具体的类型
func (v Value)Interface()(i interface())
//八alue自身也提供丰富的方法,直接将1a1ue转换为简单类型实例,如果类型不匹配,则直接引起panic
func (v Value)Bool()bool
func (v Value)Float()float64
func (v Value)Int()int64
func (v Value)Uint()uint64
  1. 从Value的指针到值
    从一个指针类型的Value获得值类型Value有两种方法,示例如下。
//如果v类型是接口,则Elem()返回接口绑定的实例的1a1ue,如果v类型是指针,则返回指
//针值的alue,否则引起panic
func (v Value)Elem()Value
//如果v是指针,则返回指针值的Value,否则返回7自身,该函数不会引起panic
func Indirect(v Value)Value
  1. Type指针和值的相互转换

指针类型Type到值类型Type。例如:

//t必须是Array、Chan、Map、Ptr、Slice,否则会引起panic
//Elem返回的是其内部元素的Type
t.Elem()Type

值类型Type到指针类型Type。例如:

//PtrTo返回的是指向t的指针型Type
func PtrTo(t Type)Type
  1. Value值的可修改性
Value值的修改涉及如下两个方法
//通过CanSet判断是否能修改
func (v Value)CanSet()bool
//通过Set进行修改
func (v Value)Set(x Value)

Vlue值在什么情况下可以修改?我们知道实例对象传递给接口的是一个完全的值拷贝,如果调用反射的方法reflect.ValueOf()传进去的是一个值类型变量,则获得的Value实际上是原对象的一个副本,这个Vlue是无论如何也不能被修改的。如果传进去的是一个指针,虽然接口
内部转换的也是指针的副本,但通过指针还是可以访问到最原始的对象,所以此种情况获得的Value是可以修改的。下面来看一个简单的示例。

package main

import (
	"fmt"
	"reflect"
)

func main() {
	u := User{Id: 1, Name: "andes", Age: 20}

	va := reflect.ValueOf(u)
	vb := reflect.ValueOf(&u)

	//值类型是不可修改的,指针类型是可修改的
	fmt.Println(va.CanSet(), va.FieldByName("Name").CanSet())        //false false
	fmt.Println(vb.CanSet(), vb.Elem().FieldByName("Name").CanSet()) //false true

	fmt.Printf("%v\n", vb)//&{1 andes 20}
	name := "shine"
	vc := reflect.ValueOf(name)

	//通过Set函数修改变量的值
	vb.Elem().FieldByName("Name").Set(vc)
	fmt.Printf("%v\n", vb)//&{1 andes 20}
}

type User struct {
	Id   int
	Name string
	Age  int
}

2、反射三定律

  1. 反射可以从接口值得到反射对象。
  2. 反射可以从反射对象获得接口值。
  3. 若要修改一个反射对象,则其值必须可以修改。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go——反射规则 的相关文章

  • 针对通过 SSH 连接到 Azure Linux VM 时发生的失败、错误或被拒绝问题进行故障排除...

    本文内容 快速故障排除步骤排查 SSH 连接问题的可用方法使用 Azure 门户使用 Azure CLI 2 0使用 VMAccess 扩展使用 Azure CLI 1 0重新启动 VM重新部署 VM使用经典部署模型创建的 VM其他资源 尝
  • Ubuntu基本命令--apt, dpkg

    一 Ubuntu中软件安装方法 1 APT方式 xff08 1 xff09 普通安装 xff1a apt get install softname1 softname2 xff08 2 xff09 修复安装 xff1a apt get f
  • 初识Mybatis

    1 框架的概念 框架 xff08 Framework xff09 是一个提供了可重用的公共结构的半成品 它为我们创建新的应用程序提供了极大的便利 一方面提供了可以拿来就用的工具 xff0c 更重要的是 xff0c 提供了可重用的设计 对应用
  • ES date_histogram 聚合

    如下 GET cars index search 34 size 34 0 34 aggs 34 34 sales 34 34 date histogram 34 按照日期时间聚合分析数据 34 field 34 34 sold 34 分析
  • python采集websocket实时数据

    之前大部分的数据采集基本都是http的 xff0c 也一直对如何采集websocket的实时数据有疑问 xff0c 不知道入从哪里入手 xff0c 一筹莫展 xff0c 今天在知乎上看到了一篇采集websocket的文章 xff0c 讲的很
  • Python安装pyinstaller方法,以及将项目生成可执行程序的步骤

    pyinstaller安装方法 前提 xff1a 确保计算机安装了Python语言环境 xff0c 并且正确配置了环境变量 方法一 xff1a 联网在线自动安装 选择一 Windows OS下进入cmd xff08 命令行窗口 xff09
  • 【JavaScript】对 Map 类的实例使用方括号 [] 运算符,会发生什么?

    span class token keyword const span f span class token operator 61 span span class token keyword new span span class tok
  • 画伯德图及相位、幅值裕度

    s域 xff1a 无滞后 xff1a num 61 122 0501 den 61 0 8190 1 g 61 tf num den margin g grid on 有滞后 xff1a gt gt num 61 106 9389 gt g
  • sed命令参数之-r -i

    对于初学linux的朋友来说 xff0c 能记住命令附带的一大帮参数就以及非常不容易了 好不容易把该用的参数都想全了 sed irns 后面一大片脚本 xff0c 一执行出错了 what 创建一下测试环境 head etc passwd g
  • Keil5 如何安装STM32 芯片包

    http www keil com dd2 Pack 从该网址下载 相应芯片的PACK 包 转载于 https www cnblogs com long5683 p 10532012 html
  • Win10 LTSB 2016 激活

    以管理员权限打开 命令提示符 xff0c 输入一代码 一行一行复制 xff0c 回车 slmgr skms kms digiboy ir slmgr ato 转载于 https www cnblogs com kjcy8 p 1123701
  • 阿里在线测评

    在一个10 10的棋盘上 xff0c 每个格子有一个分数值 xff08 非负整数 xff09 一个棋子从棋盘上的某一个起始位置移动到某一个终止位置 棋子每次在棋盘上可以朝上下左右4个方向移动 xff0c 一共最多可以移动n步 每移动到一个格
  • [Win32]一个调试器的实现(十)显示变量

    上回介绍了微软的符号模型 xff0c 有了这个基础知识 xff0c 这回我们向 MiniDebugger 中添加两个新功能 xff0c 分别是显示变量列表和以指定类型显示内存内容 显示变量列表用于列出当前函数内的局部变量或者全局变量 xff
  • VS中工程的“依赖”,“库目录”,“包含目录”

    写多了Vs中的工程 xff0c 就会遇到很多环境配置问题 xff0c 例如 依赖项 xff0c 库目录 xff0c 包含目录 等等等等 今天要记录的就是这些的基本含义 xff1a 我们拿一个例子来看 xff0c 更加清晰易懂一些 xff1a
  • vue组件websocket服务器,vue 使用WebSocket 连接

    什么是WebSocket xff1f HTML5 WebSocket WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议 WebSocket 使得客户端和服务器之间的数据交换变得更加简单 xff0c
  • openstack计算节点的zone划分

    初步了解了一些openstack zone的使用方法 xff0c 觉得比较实用 xff0c 在此分享给大家 xff1a nova aggregate list Print a list of all aggregates nova aggr
  • mysql limit查询优化(数据量大的时候很优)

    mysql limit查询优化 转载 由于limit经常用到 xff0c 却没有注意 xff0c 因为平时做的项目都比较小 xff0c 所以也没有考虑去怎么优化 xff0c 今天看了一篇关于mysql limit优化的文章 xff0c 感觉
  • Qt学习(一)ui界面的设计

    这几天初步接触了Qt xff0c 首先在学习Qt的UI界面的设计 xff0c 发现Qt里面自带的那些控件与窗体显示效果都不太好 xff0c 于是上网看了一些教程 xff0c 也参考了一个demo界面 xff0c 然后初步设计了一个ui界面
  • JWT签名与验签

    签名Token生产 using System using System Collections Generic using System IdentityModel Tokens Jwt using System Linq using Sy
  • 安装Discuz!论坛时提示“mysqli_connect() 不支持 advice_mysqli_connect”

    安装Discuz 论坛时提示 不支持Mysql数据库 xff0c 无法安装论坛 的解决方法1 在系统的 system32 xff08 C windows system32 xff09 目录下缺少libmysql dll文件 xff0c 解决

随机推荐