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

Go语言断言和类型查询

Go语言断言和类型查询

1、类型断言

类型断言(Type Assertion)是一个使用在接口值上的操作,用于检查接口类型变量所持有的值是否实现了期望的接

口或者具体的类型。

在Go语言中类型断言的语法格式如下:

// i.(TypeNname)
value, ok := x.(T)

其中,x 表示一个接口的类型,如果是具体类型变量,则编译器会报non-interface type xxx on left,T 表

示一个具体的类型(也可为接口类型)。

该断言表达式会返回 x 的值(也就是 value)和一个布尔值(也就是 ok),可根据该布尔值判断 x 是否为 T 类

型:

  • 如果 T 是具体某个类型,类型断言会检查 x 的动态类型是否等于具体类型 T。如果检查成功,类型断言返回的

    结果是 x 的动态值,其类型是 T。

  • 如果 T 是接口类型,类型断言会检查 x 的动态类型是否满足 T。如果检查成功,x 的动态值不会被提取,返回

    值是一个类型为 T 的接口值。

  • 无论 T 是什么类型,如果 x 是 nil 接口值,类型断言都会失败。

示例代码如下:

package mainimport ("fmt"
)func main() {var x interface{}x = 10value, ok := x.(int)// 10,truefmt.Print(value, ",", ok)
}

运行结果如下:

# 程序结果
10,true

需要注意如果不接收第二个参数也就是上面代码中的 ok,断言失败时会直接造成一个 panic,如果 x 为 nil 同样也

会 panic。

示例代码如下:

package mainimport ("fmt"
)func main() {var x interface{}x = "Hello"value := x.(int)fmt.Println(value)
}

运行结果如下:

# 输出结果
panic: interface conversion: interface {} is string, not int

接口断言通常可以使用 comma,ok 语句来确定接口是否绑定某个实例类型,或者判断接口绑定的实例类型是否实

现另一个接口。

re,ok := body.(io.ReadCloser)
if,ok :=  r.Body.(*maxBytesReader);

2、类型查询

接口类型查询的语法格式如下:

switch v := i.(type){case typel:XXXXcase type2:XXXXdefault:XXXX
}

接口查询有两层语义,一是查询一个接口变量底层绑定的底层变量的具体类型是什么,二是查询接口变量绑定的底

层变量是否还实现了其他接口。

(1)、i 必须是接口类型

具体类型实例的类型是静态的,在类型声明后就不再变化,所以具体类型的变量不存在类型查询,类型查询一定是

对一个接口变量进行操作。也就是说,上文中的i必须是接口变量,如果i是未初始化接口变量,则v的值是 nil。

package mainimport ("fmt""io"
)func main() {var i io.Reader//此处i是为未初始化的接口变量,所以v为nilswitch v := i.(type) {case nil://<nil>fmt.Printf("%T\n", v)default:fmt.Printf("default")}
}

(2)、case 字句后面可以跟非接口类型名,也可以跟接口类型名,匹配是按照 case 子句的顺序进行的。

  • 如果 case 后面是一个接口类型名,且接口变量i绑定的实例类型实现了该接口类型的方法,则匹配成,v的类

    型是接口类型,v底层绑定的实例是i绑定具体类型实例的副本。

  • 如果 case 后面是一个具体类型名,且接口变量i绑定的实例类型和该具体类型相同,则匹配成功,此时v 就是

    该具体类型变量,v的值是i绑定的实例值的副本。

  • 如果 case 后面跟着多个类型,使用逗号分隔,接口变量i绑定的实例类型只要和其中一个类型匹配,则直接使

    用o赋值给v,相当于 v:=o。这个语法有点奇怪,按理说编译器不应该允许这种操作,语言实现者可能想让

    type switch 语句和普通的 switch 语句保持一样的语法规则,允许发生这种情况。

  • 如果所有的case字句都不满足,则执行 default 语句,此时执行的仍然是 v:=o,最终v的值是o。此时使用v没

    有任何意义。

  • fallthrough 语句不能在 Type Switch 语句中使用。

package mainimport ("fmt""io""log""os"
)func main() {var i io.Reader// 此处i是为未初始化的接口变量,所以v为nilswitch v := i.(type) {case nil:// <nil>fmt.Printf("%T\n", v)default:fmt.Printf("default")}f, err := os.OpenFile("notes.txt", os.O_RDWR|os.O_CREATE, 0755)if err != nil {log.Fatal(err)}defer f.Close()i = fswitch v := i.(type) {// i的绑定的实例是*osFile类型,实现了io.ReadWriter接口,所以下面case匹配成功case io.ReadWriter:// v是io.ReadWriter接口类型,所以可以调用Write方法v.Write([]byte("io.ReadWriter\n"))// Type Switch Result: io.ReadWriterfmt.Println("Type Switch Result: io.ReadWriter")// 由于上一个case已经匹配,就算这个case也匹配,也不会走到这里case *os.File:v.Write([]byte("*os.File\n"))fmt.Println("Type Switch Result: *os.File")//这里可以调用具体类型方法v.Sync()default:fmt.Println("Type Switch Result: unknown")return}switch v := i.(type) {// 匹配成功,v的类型就是具体类型*os.Filecase *os.File:v.Write([]byte("*os.File\n"))// Type Switch Result: *os.Filefmt.Println("Type Switch Result: *os.File")v.Sync()//由于上一个case已经匹配,就算这个case也匹配,也不会走到这里case io.ReadWriter://v是io.ReadWriter接口类型,所以可以调用Write方法v.Write([]byte("io.ReadWriter\n"))fmt.Println("Type Switch Result: io.ReadWriter")default:fmt.Println("Type Switch Result: unknown")return}switch v := i.(type) {//多个类型,f满足其中任何一个就算匹配case *os.File, io.ReadWriter:// 此时相当于执行力v := i ,v和i是等价的,使用v没有意义。if v == i {// truefmt.Println(true)}default:return}
}
# 程序输出
<nil>
Type Switch Result: io.ReadWriter
Type Switch Result: *os.File
true
package mainimport ("fmt"
)func main() {var a inta = 10// the type of a is intgetType(a)
}func getType(a interface{}) {switch a.(type) {case int:fmt.Println("the type of a is int")case string:fmt.Println("the type of a is string")case float64:fmt.Println("the type of a is float")default:fmt.Println("unknown type")}
}
# 程序输出
the type of a is int

相关文章:

Go语言断言和类型查询

Go语言断言和类型查询 1、类型断言 类型断言(Type Assertion)是一个使用在接口值上的操作&#xff0c;用于检查接口类型变量所持有的值是否实现了期望的接 口或者具体的类型。 在Go语言中类型断言的语法格式如下&#xff1a; // i.(TypeNname) value, ok : x.(T)其中&…...

02 Deep learning algorithm

Neural Networks target&#xff1a; inference&#xff08;prediction&#xff09;training my own modelpractical advice for building machine learning systemdecision Tress application: speech&#xff08;语音识别&#xff09; ----> images(计算机视觉)—> t…...

代码随想录算法训练营第二十四天 | 回溯算法

理论基础 代码随想录原文 什么是回溯法 回溯也可以叫做回溯搜索法&#xff0c;它是一种搜索的方式。 回溯是递归的副产品&#xff0c;只要有递归就会有回溯。 回溯法的效率 虽然回溯法很难&#xff0c;不好理解&#xff0c;但是回溯法并不是什么高效的算法。因为回溯的本…...

Spring Cloud Gateway 缓存区异常

目录 1、问题背景 2、分析源码过程 3、解决办法 最近在测试环境spring cloud gateway突然出现了异常&#xff0c;在这里记录一下&#xff0c;直接上干货 1、问题背景 测试环境spring cloud gateway遇到以下异常 DataBufferLimitException: Exceeded limit on max bytes t…...

Spring Boot依赖版本声明

链接 官网 Spring Boot文档官网&#xff1a;​​​​​​https://docs.spring.io/spring-boot/docs/https://docs.spring.io/spring-boot/docs/ Spring Boot 2.0.7.RELEASE Spring Boot 2.0.7.RELEASE reference相关&#xff1a;https://docs.spring.io/spring-boot/docs/2.…...

Java项目:109SpringBoot超市仓管系统

博主主页&#xff1a;Java旅途 简介&#xff1a;分享计算机知识、学习路线、系统源码及教程 文末获取源码 一、项目介绍 超市仓管系统基于SpringBootMybatis开发&#xff0c;系统使用shiro框架做权限安全控制&#xff0c;超级管理员登录系统后可根据自己的实际需求配角色&…...

【React系列】Redux(三) state如何管理

本文来自#React系列教程&#xff1a;https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzg5MDAzNzkwNA&actiongetalbum&album_id1566025152667107329) 一. reducer拆分 1.1. reducer代码拆分 我们来看一下目前我们的reducer&#xff1a; function reducer(state ini…...

3D 纹理的综合指南

在线工具推荐&#xff1a;3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 我们经常看到超现实主义的视频游戏和动画电影角色出现在屏幕上。他们皮肤上的…...

LLM之RAG实战(十一)| 使用Mistral-7B和Langchain搭建基于PDF文件的聊天机器人

在本文中&#xff0c;使用LangChain、HuggingFaceEmbeddings和HuggingFace的Mistral-7B LLM创建一个简单的Python程序&#xff0c;可以从任何pdf文件中回答问题。 一、LangChain简介 LangChain是一个在语言模型之上开发上下文感知应用程序的框架。LangChain使用带prompt和few-…...

VLOOKUP的使用方法

VLOOKUP是Excel中一个非常有用的函数&#xff0c;用于在一个表格或范围中查找某个值&#xff0c;并返回该值所在行或列的相应数据。 VLOOKUP函数的基本语法如下&#xff1a; VLOOKUP(lookup_value, table_array, col_index_num, [range_lookup])lookup_value&#xff1a;要查…...

数据加密、端口管控、行为审计、终端安全、整体方案解决提供商

PC端访问地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 以下是关于这几个概念的解释&#xff1a; 数据加密&#xff1a;这是一种通过加密算法和密钥将明文转换为密文&#xff0c;以及通过解密算法和解密密钥将密文恢复为明文…...

编码器原理详解

编码器 什么是编码器 编码器可以用来将信息编码成为二进制代码&#xff0c;有点类似于取代号&#xff0c;人为的将二进制代码与对应的信息联系起来。 如下图所示&#xff1a; 假设有这三种情况会发生&#xff0c;且每次只发生一种情况 为了给这三种情况做一个区分&#xff…...

linux下docker搭建mysql8

1&#xff1a;环境信息 centos 7,mysql8 安装docker环境 2.创建mysql容器 2.1 拉取镜像 docker pull mysql:8.0.23 2.2 查询镜像拉取成功 docker images 2.3 创建挂载的目录文件 mkdir /usr/mysql8/conf mkdir /usr/mysql8/data ##给data文件赋予操作权限 chmod 777 /…...

书生·浦语大模型实战1

书生浦语大模型全链路开源体系 视频链接&#xff1a;书生浦语大模型全链路开源体系_哔哩哔哩_bilibili 大模型之所以能收到这么高的关注度&#xff0c;一个重要原因是大模型是发展通用人工智能的重要途径 深度信念网络&#xff1a; &#xff08;1&#xff09;又被称为贝叶斯网…...

前端JS加密对抗由浅入深-1

前言&#xff1a; 本文主要讲解&#xff0c;针对前端加密数据传输站点&#xff0c;如何进行动态调试以获取加密算法、秘钥&#xff0c;本次实验不涉及漏洞挖掘&#xff0c;仅为学习演示&#xff0c;环境为本地搭建环境 此次站点加密方式为AES加密方式&#xff0c;现如今越来越…...

八股文打卡day17——计算机网络(17)

面试题&#xff1a;拥塞控制是怎么实现的&#xff1f; 我的回答&#xff1a; 1.慢启动 在连接刚建立的时候&#xff0c;会缓慢调大滑动窗口的大小&#xff0c;从而加大网络传输速率&#xff0c;避免速率太快&#xff0c;造成拥塞。 2.拥塞避免 慢启动之后&#xff0c;会进入拥…...

Java-经典算法-logcat获取数据

1 需求 2 语法 3.1 示例&#xff1a;打印本次查询数据 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader;/*** 功能&#xff1a;adb logcat -b main -s PRIVA_LOG -d*/ public class Test {public …...

APache 网页优化

技能目标&#xff1a; 掌握 Apache 网页压缩 掌握 Apache 网页缓存 掌握 Apache 网页防盗链 掌握 Apache 隐藏版本信息 4.1 网页压缩与缓存 在使用 Apache 作为 Web 服务器的过程中&#xff0c;只有对 Apache 服务器进行适当的优化配 置&…...

C语言实现关键字匹配算法(复制即用)

文章目录 前言功能要求运行截图全部代码 前言 无套路&#xff0c;均已上机通过&#xff0c;求个关注求个赞&#xff0c;提供答疑解惑服务。 功能要求 一份C源代码存储在一个文本文件中&#xff0c;请统计该文件中关键字出现的频度&#xff0c;并按此频度对关键字进行排序。要…...

【大数据】安装 Zookeeper 单机版

安装 Zookeeper 单机版 下面安装 Zookeeper&#xff0c;由于它是 Apache 的一个顶级项目&#xff0c;所以域名是 zookeeper.apache.org&#xff0c;所有 Apache 的顶级项目的官网都是以项目名 .apache.org 来命名的。 点击 Download 即可下载&#xff0c;这里我们选择的版本是 …...

SVG Crowbar:轻松提取网页SVG内容的高效工具

SVG Crowbar&#xff1a;轻松提取网页SVG内容的高效工具 【免费下载链接】svg-crowbar Extracts an SVG node and accompanying styles from an HTML document and allows you to download it all as an SVG file. 项目地址: https://gitcode.com/gh_mirrors/sv/svg-crowbar …...

手把手教你用ROS2和ZED2 SDK搭建3D视觉开发环境(Ubuntu 20.04版)

手把手教你用ROS2和ZED2 SDK搭建3D视觉开发环境&#xff08;Ubuntu 20.04版&#xff09; 在自动驾驶、增强现实和机器人导航等领域&#xff0c;3D视觉感知已成为核心技术之一。ZED2相机凭借其双目深度感知能力和高精度SLAM算法&#xff0c;成为开发者构建空间智能系统的首选传感…...

MoMask终极指南:5分钟学会AI生成3D人体运动动画

MoMask终极指南&#xff1a;5分钟学会AI生成3D人体运动动画 【免费下载链接】momask-codes Official implementation of "MoMask: Generative Masked Modeling of 3D Human Motions (CVPR2024)" 项目地址: https://gitcode.com/gh_mirrors/mo/momask-codes 想…...

VirtualBox虚拟机磁盘空间分配技巧:如何用动态分配40G空间玩转Debian 12

VirtualBox磁盘空间动态分配实战&#xff1a;以Debian 12为例的40GB高效配置指南 在虚拟化技术日益普及的今天&#xff0c;VirtualBox作为一款开源免费的虚拟化工具&#xff0c;凭借其跨平台特性和易用性&#xff0c;成为众多开发者和技术爱好者的首选。然而&#xff0c;许多用…...

从硬件迷宫到macOS殿堂:OpCore Simplify如何重塑黑苹果配置体验

从硬件迷宫到macOS殿堂&#xff1a;OpCore Simplify如何重塑黑苹果配置体验 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 对于许多技术爱好者来说&a…...

OpCore Simplify:终极指南!让黑苹果配置从8小时缩短到45分钟的自动化神器

OpCore Simplify&#xff1a;终极指南&#xff01;让黑苹果配置从8小时缩短到45分钟的自动化神器 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 还在…...

WSABuilds GitHub Actions构建流程解析:自动化CI/CD管道配置

WSABuilds GitHub Actions构建流程解析&#xff1a;自动化CI/CD管道配置 【免费下载链接】WSABuilds Run Windows Subsystem For Android on your Windows 10 and Windows 11 PC using prebuilt binaries with Google Play Store (MindTheGapps) and/or Magisk or KernelSU (ro…...

光纤布拉格光栅(FBG)笔记【2】:传感机制与布拉格波长调谐分析

1. 光纤布拉格光栅的传感机制揭秘 第一次接触光纤布拉格光栅(FBG)传感时&#xff0c;我完全被它"以光测万物"的能力震撼了。这根比头发还细的光纤&#xff0c;竟然能精准感知温度、应变等物理量的变化。经过多次实验验证&#xff0c;我发现它的核心秘密就藏在布拉格波…...

图像超分新思路:拆解SCNet的‘空间移位’操作,看它如何用零参数实现3x3卷积的效果

图像超分辨率革命&#xff1a;零参数空间移位如何颠覆传统卷积设计 当你在手机相册里翻出一张十年前的老照片&#xff0c;是否曾幻想过能一键修复那些模糊的像素&#xff1f;这正是图像超分辨率技术试图解决的难题。传统方法依赖计算密集的33卷积&#xff0c;而SCNet提出的&quo…...

UE4/UE5碰撞事件全解:从Overlap到Hit的7个必知配置项

UE4/UE5碰撞系统深度解析&#xff1a;从基础配置到实战避坑指南 在虚幻引擎开发中&#xff0c;碰撞系统是构建交互体验的核心支柱之一。无论是角色移动、物体交互还是战斗判定&#xff0c;都离不开精准的碰撞检测机制。本文将深入剖析UE4/UE5中Overlap与Hit事件的本质区别&…...