【golang】怎样判断一个变量的类型?
怎样判断一个变量的类型?
package mainimport "fmt"var container = []string{"zero", "one", "two"}
func main() {container := map[int]string{0: "zero", 1: "one", 2: "two"}fmt.Printf("The element is %q.\n", container[1])
}
那么,怎样在打印其中元素之前,正确判断变量container的类型?
典型回答
使用类型断言
value, ok := interface{}(container).([]string)
这里有一条赋值语句。在赋值符号的右边,是一个类型断言表达式。
它包括了用来把container变量的值转换为空接口值的interface{}(container)。
以及一个用于判断前者的类型是否为切片类型[]string的.([]string)。
这个表达式的结果可以被赋给两个变量,在这里由value和ok代表。变量ok是布尔(bool)类型的,它将代表类型判断的结果,true和false。
如果是true,那么被判断的值将会被自动转换为[]string类型的值,并赋给变量value,否则value将被赋予nil(即“空”)。
顺便提一下,这里的ok也可以没有。也就是说,类型断言表达式的结果,可以只被赋给一个变量,在这里是value。
问题解析
类型断言表达式的语法形式是x.(T)。其中的x代表要被判断类型的值。这个值当下的类型必须是接口类型的,不过具体是哪个接口类型其实是无所谓的。
所以,当这里container变量类型不是任何的接口类型时,我们就需要先把它转成某个接口类型的值。
在Go语言中,interface{}代表空接口,任何类型都是它的实现类型。
你可能会对这里的{}产生疑惑,为什么在关键字interface的右边还要加上这个东西?
请记住,一对不包裹任何东西的花括号,除了可以代表空的代码块之外,还可以用于表示不包含任何内容的数据结构(或者说数据类型)。

我们向答案的最右边看。圆括号中[]string是一个类型字面量。所谓类型字面量,就是用来表示数据类型本身的若干个字符。
比如,string是表示字符串类型的字面量,uint8是表示 8 位无符号整数类型的字面量。再复杂一些的就是我们刚才提到的[]string,用来表示元素类型为string的切片类型,以及map[int]string,用来表示键类型为int、值类型为string的字典类型。
类型转换规则中有哪些值得注意的地方?
类型转换表达式已经在前面展示过,它的语法形式是T(x)。
其中的x可以是一个变量,也可以是一个代表值的字面量(比如1.23和struct{}),还可以是一个表达式。
注意:如果是表达式,那么该表达式的结果只能是一个值,而不能是多个值。在这个上下文中,x可以被叫做源值,它的类型就是源类型,而那个T代表的类型就是目标类型。
类型转化有三个很常用并且非常值得注意的知识点:
一、对于整数类型值、整数常量之间的类型转换,原则上只要源值在目标类型的可表示范围内就是合法的。
比如,之所以uint8(255)可以把无类型的常量255转换成uint8类型的值,是因为255在[0,255]的范围内。
但需要特别注意的是,源整数类型的可表示范围较大,而目标类型的可表示范围较小的情况,比如把值的类型从int16转换为int8。请看下面这段代码:
var srcInt = int16(-255)
dstInt := int8(srcInt)
变量srcInt的值是int16类型的-255,而变量dstInt的值是由前者转换而来的,类型是int8。int16类型的可表示范围可比int8类型大了不少。问题是,dstInt的值是多少?
首先你要知道,整数在 Go 语言以及计算机中都是以补码的形式存储的。这主要是为了简化计算机对整数的运算过程。补码其实就是原码各位求反再加 1。
比如,int16类型的值-255的补码是1111111100000001。如果我们把该值转换为int8类型的值,那么 Go 语言会把在较高位置(或者说最左边位置)上的 8 位二进制数直接截掉,从而得到00000001。
又由于其最左边一位是0,表示它是个正整数,以及正整数的补码就等于其原码,所以dstInt的值就是1。
一定要记住,当整数值的类型的有效范围由宽变窄时,只需在补码形式下截掉一定数量的高位二进制数即可。
类似的快刀斩乱麻规则还有:当把一个浮点数类型的值转换为整数类型值时,前者的小数部分会被全部截掉。
二、虽然直接把一个整数值转换为一个string类型的值是可行的,但值得关注的是,被转换的整数值应该可以代表一个有效的Unicode代码点,否则转换的结果将会是"�"(仅由高亮的问号组成的字符串值)。
字符"�"的Unicode代码点是U+FFFD。它是Unicode标准中定义的Replacement Character,专用于替换那些未知的、不被认可的以及无法展示的字符。
面试肯定不会去问"哪个整数值转换后会得到哪个字符串",但是可能会写下:
string(-1)
并询问会得到什么?这可是完全不同的问题啊。由于-1肯定无法代表一个有效的Unicode代码点,所以得到的总会是"�"。在实际工作中,我们在排查问题时可能会遇到"�",我们要知道这可能是由于什么引起的。
三、关于string类型与各种切片类型之间的互转的。
一个值在从string类型向[]byte类型转换时代表着以 UTF-8 编码的字符串会被拆分成零散、独立的字节。
除了与ASCII编码兼容的那部分字符集,以 UTF-8 编码的某个单一字节是无法代表一个字符的。
string([]byte{'\xe4', '\xbd', '\xa0', '\xe5', '\xa5', '\xbd'}) // 你好
比如,UTF-8 编码的三个字节\xe4、\xbd和\xa0合在一起才能代表字符’你’,而\xe5、\xa5和\xbd合在一起才能代表字符’好’。
其次,一个值在从string类型向[]rune类型转换时代表着字符串会被拆分成一个个Unicode 字符。
什么是别名类型?什么是潜在类型?
我们可以用关键字type声明自定义的各种类型。当然了,这些类型必须在 Go 语言基本类型和高级类型的范畴之内。在它们当中,有一种被叫做“别名类型”的类型。我们可以像下面这样声明它:
type MyString = string
这条声明语句表示,MyString是string类型的别名类型。顾名思义,别名类型与其源类型的区别恐怕只是在名称上,它们是完全相同的。
源类型与别名类型是一对概念,是两个对立的称呼。别名类型主要是为了代码重构而存在的。
Go 语言内建的基本类型中就存在两个别名类型。byte是uint8的别名类型,而rune是int32的别名类型。
注意,如果我这样声明:
type Mystring2 string //注意,这里没有等号。
MyString2和string就是两个不同的类型了。这里的MyString2是一个新的类型,不同于其他任何类型。
这种方式也可以被叫做对类型的再定义。我们刚刚把string类型再定义成了另外一个类型MyString2。

对于这里的类型再定义来说,string可以被称为MyString2的潜在类型。潜在类型的含义是,某个类型在本质上是哪个类型。
潜在类型相同的不同类型的值之间是可以进行类型转换的。因此,MyString2类型的值与string类型的值可以使用类型转换表达式进行互转。
但对于集合类的类型[]MyString2与[]string来说这样做却是不合法的,因为[]MyString2与[]string的潜在类型不同,分别是[]MyString2和[]string。另外,即使两个不同类型的潜在类型相同,它们的值之间也不能进行判等或比较,它们的变量之间也不能赋值。
文章来自郝林老师的《Go语言36讲》
相关文章:
【golang】怎样判断一个变量的类型?
怎样判断一个变量的类型? package mainimport "fmt"var container []string{"zero", "one", "two"} func main() {container : map[int]string{0: "zero", 1: "one", 2: "two"}fmt.Printf…...
怎么学习AJAX相关技术? - 易智编译EaseEditing
学习AJAX(Asynchronous JavaScript and XML)相关技术可以让你实现网页的异步数据交互,提升用户体验。以下是一些学习AJAX技术的步骤和资源: HTML、CSS和JavaScript基础: 首先,确保你已经掌握了基本的HTML…...
JDK、JRE、JVM:揭秘Java的关键三者关系
文章目录 JDK:Java开发工具包JRE:Java运行环境JVM:Java虚拟机关系概述 案例示例:Hello World结语 在Java世界中,你可能经常听到JDK、JRE和JVM这几个概念,它们分别代表了Java开发工具包、Java运行环境和Java…...
【reactNative混合安卓开发~使用问题持续更】
reactNative混合安卓开发 reactNative开发移动端reactNative界面开发前端init.bat文件部分组件第三方组件解析1、定义theme主题shopify/restyle;菜单导航react-navigation/drawer、react-navigation/native; RN问题记录1、使用theme.js写的公共组件报错&…...
OCR的发明人是谁?
OCR的发明背景可以追溯到早期计算机科学和图像处理的研究。随着计算机技术的不断发展,人们开始探索如何将印刷体文字转换为机器可读的文本。 OCR(Optical Character Recognition,光学字符识别)的发明涉及多个人的贡献,…...
笔记本电脑连上WiFi之后的IP为什么会变?如何让它不变固定住?
笔记本连上WiFi后获取IP地址的过程,通常是通过DHCP (动态主机配置协议) 来完成的。默认情况下,DHCP会根据连接设备和网络状态动态地分配IP地址,因此你会看到IP地址可能经常改变。 如果你希望电脑的IP地址固定,可以尝试设置静态IP…...
【数学建模】--因子分析模型
因子分析有斯皮尔曼在1904年首次提出,其在某种程度上可以被看成时主成分分析的推广和扩展。 因子分析法通过研究变量间的相关稀疏矩阵,把这些变量间错综复杂的关系归结成少数几个综合因子,由于归结出的因子个数少于原始变量的个数,…...
RAM不够?CUBEIDE使用CCMRAM
RAM不够?使用CCMRAM 文章目录 RAM不够?使用CCMRAM打开连接LD文件:添加代码添加标识宏使用 打开连接LD文件: 添加代码 在SECTIONS段最后加上下面代码: _siccmram LOADADDR(.ccmram); /* CCM-RAM section * * IMPORTAN…...
npm ERR! code ERESOLVEnpm ERR! ERESOLVE unable to resolve dependency tree
拉取项目到本地 执行 npm install 报错 遇到这个问题首先确认的就是版本是不是太高了,降一下版本。或者通过yarn命令替代npm install命令安装,同理,启动也可以采用yarn dev 启动代替npm run dev 下面教大家用一个NVM工具,这个工…...
使用 prometheus client SDK 暴露指标
目录 1. 使用 prometheus client SDK 暴露指标1.1. How Go exposition works1.2. Adding your own metrics1.3. Other Go client features 2. Golang Application monitoring using Prometheus2.1. Metrics and Labels2.2. Metrics Types2.2.1. Counters:2.2.2. Gauges:2.2.3. …...
Jmeter之BeanShell取出参数进行四则运算,并判断是否正确
首先调用余额接口,使用正则提取响应中的余额字段,记作变量acctBal1做支付交易再次调用余额接口,使用正则提取响应中的余额字段,记作变量acctBal2最后在结果树中可以看到断言错误的信息,断言正确时没有提示以下是beansh…...
PYTHON 斗地主发牌 (简易版)
利用方法: 1. random.randint( ) 随机抽取数字 方法 2.random.sample((抽取范围的参数),(抽取的个数)) 返回的是列表 所以用[0]可以输出里面的元素 import random# 1. 创建牌 # 花色 color ["\u2660", "\u2663", "\u2665", "\…...
CSS文本裁剪
对于单行文本裁剪: span {text-overflow:ellipsis;white-space:nowrap;overflow:hidden;display:block; } 对于多行文本裁剪: 在文本容器上定义 CSS Flexbox 属性 display: -webkit-box; 定义要显示的文本行数 -webkit-line-clamp: 4; 添加 -webkit-…...
ClickHouse常见的引擎和使用
1.日志引擎 日志引擎特点 1.数据存储在磁盘上 2.写入时将数据追加在文件末尾 3.不支持突变操作 4.不支持索引 5.非原子地写入数据 6.引擎不支持 ALTER UPDATE 和 ALTER DELETE 操作 建表语法示例 CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] ( …...
构建之法 - 软件工程实践教学:一线教师的13问
福州大学单红老师的软工课程总结 2020春,不一样的学期不一样的软工实践 单红⽼师在总结中,提出了13条疑惑,《构建之法》的作者邹欣⽼师就单红⽼师提出的每⼀条疑惑,给出了⾃⼰的思考,与他进⾏探讨交流。欢迎你也来参与…...
联调 matlab 遇到的一些事儿
记录当时遇到的问题,因为平时不写 matlab,所以没有深入的理解。 版本兼容 当时遇到的第一个问题就是不同版本 matlab 带来的兼容性问题。同时开发使用的是 2021a 版本,而调试时使用的是 2022b 版本。在新版本中某些函数已被弃用,…...
时序预测 | Matlab实现基于GRNN广义回归神经网络的电力负荷预测模型
文章目录 效果一览文章概述源码设计参考资料效果一览 文章概述 时序预测 | Matlab实现基于GRNN广义回归神经网络的电力负荷预测模型 1.Matlab实现基于GRNN广义回归神经网络的电力负荷预测模型 2.单变量时间序列预测; 3.多指标评价,评价指标包括:R2、MAE、MBE等,代码质量极高…...
3.2 Tomcat基础
1. Tomcat概述 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器。 Tomcat版本:apache-tomcat-8.5.76。 2.IDEA集成Tomcat 第一步 第二步 第三步 编辑切换为居中 添加图片注释,不超过 140 字࿰…...
认识http的方法、Header、状态码以及简单实现一个http的业务逻辑
文章目录 http的方法http状态码http重定向http常见Header实现简单业务逻辑Protocol.hppUtil.hppServer.hppServer.cc 效果 http的方法 方法说明支持的HTTP版本GET获取资源1.0/1.1POST传输实体主体1.0/1.1PUT传输文件1.0/1.1HEAD获得报文首部1.0/1.1DELETE删除文件1.0/1.1OPTIO…...
Faiss在windows下安装和使用
pip install faiss-cpu 直接安装可能出现问题: error: command swig.exe failed: No such file or directory 安装swig即可解决,安装方式...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
