通过一个题目三种变式讲清楚go接口类型断言
【第一种】一种类型实现多个接口,各个接口变量调用各自的方法
type Work struct {
i int
}
func (w Work) ShowA() int {
return w.i + 10
}
func (w Work) ShowB() int {
return w.i + 20
}
func main() {
c := Work{3}
var a A = c
var b B = c
fmt.Println(a.ShowA())
fmt.Println(b.ShowB())
}
输出:13 23。
一种类型实现多个接口,结构体 Work 分别实现了接口 A、B,所以接口变量 a、b 调用各自的方法 ShowA() 和 ShowB(),输出 13、23。
【第二种】一种类型实现多个接口,各个接口变量调用不是自己的方法
type Work struct {
i int
}
func (w Work) ShowA() int {
return w.i + 10
}
func (w Work) ShowB() int {
return w.i + 20
}
func main() {
c := Work{3}
var a A = c
var b B = c
fmt.Println(a.ShowB())
fmt.Println(b.ShowA())
}
a、b 具有相同的动态类型和动态值,分别是结构体 work 和 {3};a 的静态类型是 A,b 的静态类型是 B,接口 A 不包括方法 ShowB(),接口 B 也不包括方法 ShowA(),编译报错。
【第三种】一种类型实现多个接口,各个接口变量进行类型转换后,调用不是自己的方法
type A interface {
ShowA() int
}
type B interface {
ShowB() int
}
type Work struct {
i int
}
func (w Work) ShowA() int {
return w.i + 10
}
func (w Work) ShowB() int {
return w.i + 20
}
func main() {
var a A = Work{3}
s := a.(Work)
fmt.Println(s.ShowA())
fmt.Println(s.ShowB())
}
输出:13 23。
通过类型断言将接口变量 a 转换为具体类型 Work。
调用 Work 类型的方法 ShowA 和 ShowB,并根据 w.i 的值计算结果。
底层原理
这涉及到了 Go 语言中的接口和类型断言的底层原理。
接口的内部表示:
- 在 Go 中,接口的内部表示包括两部分:值和类型指针。
- 当一个类型被赋值给一个接口变量时,会将这个值的副本存储在接口的值部分,同时将指向类型信息的指针存储在接口的类型部分。
类型断言:
- 类型断言允许我们从接口中检索其动态类型的值。
- 当我们使用类型断言将接口值转换为具体类型时,Go 会检查接口的动态类型和我们所期望的类型是否匹配。
- 如果匹配,类型断言会返回具体类型的值;如果不匹配,则会导致运行时恐慌。
在这个例子中,虽然变量 a 是一个 A 类型的接口变量,但它包含的是一个 Work 类型的值,所以它实际上拥有 Work 类型的方法集。因此,当我们将 a 进行类型断言,转换为 Work 类型的值 s 时,s 实际上是一个 Work 类型的变量,它可以调用 Work 类型的所有方法,包括 ShowB()。
这就是为什么在这个例子中,尽管 a 是一个 A 类型的接口变量,但我们仍然可以调用 s.ShowB() 而不会报错。因为在运行时,s 是一个 Work 类型的变量,而 Work 类型有 ShowB() 方法。
通过一个题目三种变式讲清楚go接口类型断言的更多相关文章
- String js删除字符串的最后一个字符三种方法
字符串 var basic = "abc,def,ghi,"; 第一种 basic = basic.substr(0, basic.length - 1); 第二种 basic = ...
- js删除字符串的最后一个字符三种方法
字符串 var basic = "abc,def,ghi,"; 第一种 basic = basic.substr(0, basic.length - 1); 第二种 basic = ...
- HIbernate学习笔记(二) hibernate对象的三种状态与核心开发接口
1.在hibernate中持久化对象有三个状态,这个面试时可能会问到: (1)transient瞬时态:在数据库中没有与之匹配的数据,一般就是只new出了这个对象,并且在session缓存中也没有即此 ...
- Spring IOC 三种注入方式(构造器,setter,接口)
Spring的依赖注入有三种方式: 1,构造器注入 2,setter注入 3,接口注入 下面我给大家介绍一下这三种注入 1.构造器注入 构造器注入主要是依赖于构造方法去实现,构造方法可以是有参也可以是 ...
- 三种方法实现调用Restful接口
1.基本介绍 Restful接口的调用,前端一般使用ajax调用,后端可以使用的方法比较多, 本次介绍三种: 1.HttpURLConnection实现 2.HttpClient实现 3.Spring ...
- Servlet学习笔记(1)--第一个servlet&&三种状态对象(cookie,session,application)&&Servlet的生命周期
servlet的404错误困扰了两天,各种方法都试过了,翻书逛论坛终于把问题解决了,写此博客来纪念自己的第一个servlet经历. 下面我会将自己的编写第一个servlet的详细过程提供给初学者,大神 ...
- 51、多线程创建的三种方式之实现Callable接口
实现Callable接口创建线程 Callable接口是在jdk5版本中加入的,这个接口在java.util.concurrent包下面,与其他两种方式不同的地方在于使用Callable接口创建的线程 ...
- OpenJDK源码研究笔记(十四):三种经典的设计方法,接口,接口-抽象类-具体实现类,接口-具体实现类
在研究OpenJDK源码过程中,我发现常用的设计方法就是2种:接口,接口-抽象类-具体实现类 . 在一些其它开源框架和业务开发中,经常存在着第3种设计,接口-具体实现类. 1.只有接口,没有实现类. ...
- 50、多线程创建的三种方式之实现Runnable接口
实现Runnable接口创建线程 使用Runnable创建线程步骤: package com.sutaoyu.Thread; //1.自定义一个类实现java.lang包下的Runnable接口 cl ...
- SQL Server三种表连接原理
在SQL Server数据库中,查询优化器在处理表连接时,通常会使用一下三种连接方式: 嵌套循环连接(Nested Loop Join) 合并连接 (Merge Join) Hash连接 (Hash ...
随机推荐
- Superviso可视化监控进程
如果您需要同时运行多个 ThinkPHP 命令,可以在 Supervisor 中为每个命令创建一个单独的程序段.以下是示例配置,其中包含两个 ThinkPHP 命令:command1.php 和 co ...
- java web 开发框架编
学习web 框架上开发需要的是安装 mysql 8.0 idea 2022 git 2.2.23 node 16以上 (新版本不好拉有些库了)jdk 最好是17以上 jdk8也是行的,反正不管 ...
- 【Java】JNDI实现
前提情要: 培训的时候都没讲过,也是书上看到过这么个东西,进公司干外包的第二个项目就用了这个鬼东西 自学也不是没尝试过实现,结果各种失败,还找不到问题所在,索性不写了 JNDI实现参考: 目前参考这篇 ...
- 一文搞懂DevOps、DataOps、MLOps、AIOps:所有“Ops”的比较
引言 近年来,"Ops"一词在 IT 运维领域的使用迅速增加.IT 运维正在向自动化过程转变,以改善客户交付.传统的应用程序开发采用 DevOps 实施持续集成(CI)和持续部署( ...
- OI之奇葩错误
链式前向星(写法 \(1\)):\(head\) 数组不初始化成 \(-1\).(同学写题) 链式前向星(写法 \(2\)):\(idx\) 不初始化成 \(1\).(同学写题) 用到队列时忘记 \( ...
- 【牛客刷题】HJ6 质数因子
题目链接 这道题本身更多的是考察如何计算一个数的质数因子,更像是一道数学题,用到了循环的方法: package main import ( "fmt" "math&quo ...
- springboot认证方案一
这里给出集成oauth2后的简单认证方案架构图
- 玩客云安装hassio
docker版 安装hass镜像,首次安装比较慢 需要等几分钟启动(10分钟左右) docker run -d --restart=always --name="home-assistant ...
- 微信小程序中使用Echarts展示折线图
效果图 主要实现的功能输入地区和频次查询油价的调整消息 1.从echarts-for-weixin官网下载文件 2.项目中引入echarts 将整个文件夹放在项目pages同级的目录下面 import ...
- Chrome扩展插件的开发--获取网页Cookies
Chrome扩展插件的开发--获取网页Cookies Chrome浏览器在浏览器类应用软件中一直居于榜首,很多人选择Chrome浏览器不仅仅是因为它的稳定,还有它丰富的可拓展性.那么有没有想自己开发一 ...