当前位置: 首页 > news >正文

golang -- 如何获取变量类型

目录

  • 前言
  • 获取变量类型
    • 一、fmt.Printf
    • 二、类型断言
    • 三、类型选择
    • 四、反射 reflect.TypeOf
    • 五、reflect.Value的Type()方法

前言

在学习反射的时候,对reflect包中获取变量类型的函数很迷惑
比如下面这个 用Type获取变量类型的方法(在下面提到)
所以结合多方资料进行了学习,并整理了这篇博客

在这里插入图片描述

获取变量类型

一、fmt.Printf

直接使用 fmt.Printf 的 %T 打印变量的类型

	fmt.Printf("%T\n", 1)     //intfmt.Printf("%T\n", "abc") //stringfmt.Printf("%T\n", true)  //boolfmt.Printf("%T\n", 1.1)   //float64

二、类型断言

类型断言是Go语言中用于检查接口值的底层具体类型或将其转换为特定类型的机制。它允许从接口值中提取出具体的值,或者检查接口值是否持有特定的类型

  • 基本语法
    类型断言有两种形式:
  1. 单返回值形式:x.T( )
  2. 双返回值形式:value, ok := x.T( )
  • 单返回值形式
value := x.(T)
  1. 参数:
  • x:必须是一个接口类型的表达式
  • T:要断言的类型(可以是具体类型或另一个接口类型)
  1. 返回值:
  • 如果 x 是 T 类型,则返回 x 的值
  • 如果 x 不是 T 类型,则断言失败,会引发 panic

*** 示例:
断言成功:

	a := 1v := interface{}(a)value := v.(int)   //断言成功fmt.Println(value) //输出1

断言失败:

	a := 1v := interface{}(a)value := v.(float64) //断言失败,引发panicfmt.Println(value)

panic: interface conversion: interface {} is int, not float64

  • 双返回值形式
value, ok := x.(T)
  1. 参数:
    同单返回值形式

  2. 返回值:

  • value:如果断言成功,返回 x 的值(实际上这里存在一个类型转换,x是接口类型的变量,首先将值从interface{ }类型转换为T类型,再赋值给value);否则返回 T 类型的零值
  • ok:bool值,如果断言成功是true,断言失败是false

示例:

	value, ok := v.(string)   //断言失败fmt.Println(value, ok)    //输出“ false”  这里value不是没有输出,而是因为value是string的零值 输出空字符串fmt.Printf("%T\n", value) //输出“string”--表明value是string类型的零值value1, ok1 := v.(int)    //断言成功fmt.Println(value1, ok1)  //输出“1 true”
  1. 忽略返回值的规则
  • 忽略ok(只关心值)
value, _ := x.(T)   //忽略ok

风险:如果断言失败,value是T类型的零值,可能引发逻辑错误

  • 忽略value (只检查类型)
    如果只关心类型是否匹配,不关心具体值:
_,ok := x.(T)  //忽略value

三、类型选择

类型选择是Go语言中一种特殊的 switch 语句,用于检查接口值的动态类型。
必须和switch一起使用

  • 基本语法:
	switch v := x.(type) {case T1://v的类型是T1case T2://v的类型是T2default:}
  1. 参数
    必须是接口类型

*** 示例:

	a := 1v := interface{}(a)switch v.(type) {case int:fmt.Println("int类型")case string:fmt.Println("是string类型")default:fmt.Println("未知")}

输出

int

四、反射 reflect.TypeOf

reflect.TypeOf 是Go语言标准库中 reflect 包提供的核心函数之一,用于获取任意值的类型信息

  • 基本语法:
// TypeOf returns the reflection [Type] that represents the dynamic type of i.
// If i is a nil interface value, TypeOf returns nil.
func TypeOf(i any) Type {return toType(abi.TypeOf(i))
}
//TypeOf 返回表示 i 的动态类型的反射 [Type]。
//如果 i 是 nil 接口值,则 TypeOf 返回 nil。
  1. 参数
  • 接收参数:
    接收任意类型的值(实际上存在类型转换,在底层实现原理提到)

  • 参数传递机制:
    如果是值类型(如int、struct 等),会创建值的副本
    如果是引用类型(如slice、map、pointer等),会复制引用

  1. 返回值
  • 返回值类型: reflect.Type(接口类型)
  • 返回值内容:
    包含动态类型信息
    可以获取类型名称、种类(Kind)、方法集等
  1. 底层实现原理:
func TypeOf(i interface{}) Type 
  • 调用TypeOf(x) 时:
    编译器将x转换为接口值(包含类型指针和值指针)
    运行时从接口值中提取类型信息
    返回指向内部类型结构的 reflect.Type 接口
  • 类型描述符:
    Go运行时为每种类型维护一个类型描述符(rtype)

*** 示例:

  • 对于基本类型,
	a := "bcd"fmt.Println(reflect.TypeOf(a)) //输出:string
  • 对于结构体变量,
type Person struct {Name stringAge  int
}func main() {p := Person{"haha",18,}t := reflect.TypeOf(p)  fmt.Println(t)//遍历结构体中所有字段for i := 0; i < t.NumField(); i++ { //NumField计算结构体字段个数field := t.Field(i) //每个字段的类型和值fmt.Println(field.Name, field.Type) //field.Type和field.Kind在下面提到}
}

输出如下

main.Person
Name string
Age int

field.Name 和 field.Type

在Go语言的反射机制中,
field.Name 和 field.Type 是用于描述结构体字段的两个关键属性,
field.Name获取字段名,field.Type获取字段类型


五、reflect.Value的Type()方法

已经有一个reflect.Value时,可以通过它的Type()方法获取类型
参数必须是Value类型

*** 示例:

	v := reflect.ValueOf(3)t := v.Type()       //从Value获取Typefmt.Println(t)      //输出“int”

在这里插入图片描述


reflect.TypeOf(x) 和 v.Type() 的区别

  1. 接收参数
    reflect.TypeOf(x) :参数可以为任意类型
    v.Type() :参数为Value类型
  2. 底层实现
    reflect.TypeOf(x)内部会先创建一个interface{},然后提取类型信息
    v.Type()只是返回reflect.Value内部保存的类型信息

相关文章:

  • ISP流程介绍(Raw格式阶段)
  • 《Vuejs设计与实现》第 5 章(非原始值响应式方案) 上
  • 发那科机器人5(异常事件和程序备份加载+ROBOGUIDE离线仿真)
  • 二叉树的深度
  • Conda激活环境无效
  • 对称加密以及非对称加密
  • transformer 笔记 tokenizer moe
  • [Windows] 希捷(Seagate)硬盘官方检测工具 - SeaTools(1.4.0.7)
  • 【身份证识别表格】批量识别身份证扫描件或照片保存为Excel表格,怎么大批量将身份证图片转为excel表格?基于WPF和腾讯OCR的识别方案
  • Path to Integer_ABC402分析与解答
  • SCDN是什么?
  • 上班摸鱼远程打游戏,哪款远控软件好用点?
  • 【Bootstrap V4系列】学习入门教程之 组件-表单(Forms)
  • MySQL如何优雅的执行DDL
  • 图解gpt之神经概率语言模型与循环神经网络
  • 【应急响应】- 日志流量如何分析?
  • SecureCRT网络穿透/代理
  • 网络研讨会开发注册中, 5月15日特励达力科,“了解以太网”
  • 深入理解C/C++内存管理:从基础到高级优化实践
  • kafka 面试总结
  • 面对非专业人士,科学家该如何提供建议
  • 国家出口管制工作协调机制办公室部署开展打击战略矿产走私出口专项行动
  • 国家税务总局泰安市税务局:山东泰山啤酒公司欠税超536万元
  • 第32届梅花奖终评启幕,上海京剧院《智取威虎山》满堂彩
  • 复旦设立新文科发展基金,校友曹国伟、王长田联合捐赠1亿助力人文学科与社会科学创新
  • 中方对中美就关税谈判的立场发生变化?外交部:中方立场没有任何改变