当前位置: 首页 > 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内部保存的类型信息
http://www.xdnf.cn/news/358417.html

相关文章:

  • uniapp-商城-47-后台 分类数据的生成(通过数据)
  • Eclipse SWT 1 等比缩放
  • 菜鸟之路Day30一一MySQL之DMLDQL
  • 常见降维算法分析
  • C++进阶--红黑树的实现
  • .NET高频技术点(持续更新中)
  • 适老化洗浴辅具产业:在技术迭代与需求升级中重塑银发经济新生态
  • Vue——Axios
  • 通信协议选型篇:如何根据项目需求选择合适的通信协议?
  • 线段树:数据结构中的超级英雄
  • kafka学习笔记(四、生产者、消费者(客户端)深入研究(三)——事务详解及代码实例)
  • 一、对linux驱动文件编写时结构认识与记录
  • A* (AStar) 寻路
  • 读取传感器发来的1Byte数据:分低位先行和高位先行的处理方法
  • 【iptables】--命令基本使用
  • Web 架构之数据读写分离
  • 配置Java Selenium Web自动化测试环境
  • 5.0.5 变换(旋转、缩放、扭曲)
  • 云手机解决方案
  • 图像匹配导航定位技术 第 11 章
  • 蓝桥杯青少 图形化编程(Scratch)编程题每日一练——小猫的城堡
  • 电动汽车充换电设施可调能力聚合评估与预测 - 使用说明文档
  • Java设计模式全面详解:从基础到高级的23种模式简介
  • Vue 系列之:defineProps、defineEmits、...
  • vue3: pdf.js 2.16.105 using typescript
  • 字符函数和字符串函数
  • MKS RGA 校准调试MKS eVision和Vision 1000p RGA步骤(图文并茂)
  • 使用 Spring 和 Redis 创建处理敏感数据的服务
  • 4.2【LLaMA-Factory实战】金融财报分析系统:从数据到部署的全流程实践
  • 20250509 哲学上的真空和哲学上的虚无是一个概念吗