关于 interface{} 会有啥注意事项?上
学习 golang ,对于 interface{} 接口类型,我们一定绕不过,咱们一起来看看 使用 interface{} 的时候,都有哪些注意事项吧
interface {} 可以用于模拟多态
xdm 咱们写一个简单的例子,就举动物的例子
写一个 Animal 的接口,类似于 java 里面的抽象类 ,Animal 的接口 中有 2 个方案待实现
写一个 Cat 来继承 Animal , 实现 Eat 方法和 Drink 方法
- 动物都有吃和喝的行为,小猫吃的行为是吃鱼,小猫的喝的行为是喝可乐
- 最后在主函数中,使用父类的指针,来指向子类的实例化的一个子类地址
type Animal interface {Eat(string) stringDrink(string) string
}type Cat struct{}func (c *Cat) Eat(food string) string {if food != "fish" {return "i dislike"} else {return "i like"}}
func (c *Cat) Drink(drink string) string {if drink == "coke" {return "i love"}else{return "abandon"}
}
func main(){var a Animal = &Cat{}fmt.Println(a.Eat("fish"))fmt.Println(a.Drink("water"))
}
看到上述代码,会不会有这样的疑问,命名是 &Cat{} 是取地址的,为什么 var a Animal 不写成指针呢?
这里需要注意,Animal 本身是 接口类型,自身就是一个指针
运行上述代码查看效果
# go run main.go
i like
abandon
没有毛病,小猫眯爱吃鱼,不爱喝水
interface{} 需要注意空和非空的情况
什么叫做空的 interface{} , 什么又叫做非空的 interface{} 呢?
咱们还是用上面的例子, 添加一个 testInterface 函数,来实践一下
func testInterface() Animal {var c *Catreturn c
}func main() {test := testInterface()if test == nil {fmt.Println("test is nil")} else {fmt.Println("test is not nil")}
}
可以猜猜看,上面这个小案例会输出什么结果
- 理论上来看,
testInterface函数中我们只是创建了一个 Cat 指针,并没有赋值,因此默认是一个零值,因此会是一个 nil,那么 return 的时候,应该也是 return nil 才对吧,因此按照代码的逻辑来说应该是输出test is nil
执行上述代码后,查看结果
# go run main.go
test is not nil
看到上面的结果,是不是觉得很奇怪,和自己的预期不一致
没关系,之前的文章我们说到过,觉得一个技术点奇怪,不是我们所期望的效果,原因是我们对其原理不够了解,不够熟悉
现在先来回答一下上面的问题
空接口:意思是没有方法的接口,interface{} 源码中表示为 eface 结构体
非空接口:表示有包含方法的接口 , interface{} 源码中表示为 iface 结构体
暂时先来直接介绍源码中的结构体
iface 结构体 , 非空
type iface struct {tab *itabdata unsafe.Pointer
}type itab struct {inter *interfacetype_type *_typelink *itabhash uint32 // copy of _type.hash. Used for type switches.bad bool // type does not implement interfaceinhash bool // has this itab been added to hash?unused [2]bytefun [1]uintptr // variable sized
}
-
tab
指的是具体的类型信息,是一个 itab 结构,结构中成员如上,这里面包含的都是借口的关键信息,例如 hash 值 ,函数指针,等等,后续详细剖析 interface{} 原理的时候再统一说
-
data
具体的数据信息
eface 结构体
type eface struct {_type *_typedata unsafe.Pointer
}
type _type struct {size uintptr // 表示的是 类型的大小ptrdata uintptr // 值的是前缀指针的内存大小hash uint32 // 计算数据的 hash 值tflag tflagalign uint8 // 进行内存对齐的fieldalign uint8 kind uint8 alg *typeAlg gcdata *bytestr nameOffptrToThis typeOff
}
- _type
类型信息,和上面的 非空接口类似 , 这个_type 类型决定下面的 data 字段如何去解释数据
- data
具体的数据信息
看到这里,细心的 xdm 是不是就可以看出来,我们上面写的 Animal 接口,其实是一个非空接口,因为里面有包含方法,所以他的底层是一个 iface 结构体 ,非空接口
那么初始化的一个空指针 c ,实际上是 iface 结构体里面的 data 字段为空而已,数据为空而已,但是 iface 这个结构体自己不是空的,所以上述代码走的逻辑是 test is not nil

这里顺带说一下,golang 中,还有哪些数据结构是和 nil 比较是否为零值,这个点我们也可以看看源码
// nil is a predeclared identifier representing the zero value for a
// pointer, channel, func, interface, map, or slice type.
var nil Type // Type must be a pointer, channel, func, interface, map, or slice type
源码中有说到,可以对 指针,通道,函数,接口,map,切片类型使用 nil
好了,本次就到这里,知识点要用起来才有价值
欢迎点赞,关注,收藏
朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里
技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。
我是阿兵云原生,欢迎点赞关注收藏,下次见~
相关文章:
关于 interface{} 会有啥注意事项?上
学习 golang ,对于 interface{} 接口类型,我们一定绕不过,咱们一起来看看 使用 interface{} 的时候,都有哪些注意事项吧 interface {} 可以用于模拟多态 xdm 咱们写一个简单的例子,就举动物的例子 写一个 Animal 的…...
Matlab中旧版modem.qammod与新版不兼容
最近,因为课题需要,在研究通信。在网上下了一个2015年左右的代码,其中用的是matlab旧版中的modem.qammod函数,但是旧版中的函数已经被删除了,(这里必须得吐槽一下,直接该函数内部运行机制就行呀…...
通达信指标公式颜色代码的四种写法(COLOR/RGB)
通达信指标公式颜色代码有四种写法,分别为COLOR颜色的英文、COLOR十六进制、RGBX十六进制、RGB(R,G,B)。标题有点尴尬,让我想到孔乙己“茴”字的四种写法,哈哈。 一、COLOR颜色的英文 “COLOR颜色的英文”这种写法比较简单,函数库…...
小程序面试题收集(持续更新中...)
小程序面试题收集 1.请谈谈微信小程序主要目录和文件的作用 project.config.json:项目配置文件,用的最多的就是配置是否开启https校验App.js:设置一些全局的基础数据等App.json:底部tab,标题栏和路由等设置App.wxss&…...
最深情的告白——郁金香(Python实现)
目录 1 最深情的告白 2 即兴赞之 2.1 李小白言郁金香 2.2 郁金香般的姑娘 2.3 荷兰的郁金香 3 Python代码实现 3.1 郁金香的芬芳 3.2 我俩绚丽多姿的风景 1 最深情的告白 曾经以为,她爱玫瑰,然后我画了好几种: 花仙子——玫瑰&a…...
代码随想录算法训练营第六天|242.有效的字母异位词 、349. 两个数组的交集 、 202. 快乐数、1. 两数之和
当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。哈希法是牺牲了空间换取了时间,要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。当我们要使用集合来解决哈希问题的时候,优先使用…...
【STL】模拟实现list
目录 1、list介绍 所要实现类及其成员函数接口总览 2、结点类的模拟实现 基本框架 构造函数 3、迭代器类的模拟实现 迭代器类存在的意义 3.1、正向迭代器 基本框架 默认成员函数 构造函数 运算符重载 --运算符重载 !运算符重载 运算符重载 *运算符重载 …...
Spring Cloud Alibaba全家桶(五)——微服务组件Nacos配置中心
前言 本文小新为大家带来 微服务组件Nacos配置中心 相关知识,具体内容包括Nacos Config快速开始指引,搭建nacos-config服务,Config相关配置,配置的优先级,RefreshScope注解等进行详尽介绍~ 不积跬步,无以至…...
【微信小程序】-- 页面事件 - 下拉刷新(二十五)
💌 所属专栏:【微信小程序开发教程】 😀 作 者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! &…...
springboot启动过程加载数据笔记(springboot3)
SpringApplication AbstractApplicationContext PostProcessorRegistrationDelegate ConfigurationClassPostProcessor ConfigurationClassParser 一堆循环和调用 ComponentScanAnnotationParser扫描 processConfigurationClass.doProcessConfigurationClass(configClass, so…...
中文代码86
PK 嘚釦 docProps/PK 嘚釦諿A眎 { docProps/app.xml漅薾?糤?D?v拢W4揣狤"攃e9 睔貣m*:PAz韒g?项弇}R珁湧4嶱 ]I禑菦?櫮戵\U佳 珩 ]铒e礎??X(7弅锿?jl筀儸偛佣??z窊梈ZT炰攷 ?\ 銒沆?状尧绥>蕮 ?斬殕{do]?o乗YX?:??罢秗,泿)怟 …...
网络参考模型
OSI参考模型 应用层 不服务于任何其他层,就是位APP提供相应的服务,不如HTTP、域名解析DNS提供服务表示层 1.使得应用数据能够被不同的系统(Windows\Linux)进行识别和理解 2.数据的解码和编码、数据的加密与解密、数据的压缩和解…...
Spark Tungsten
Spark Tungsten数据结构Unsafe Row内存页管理全阶段代码生成火山迭代模型WSCG运行时动态生成Tungsten (钨丝计划) : 围绕内核引擎的改进: 数据结构设计全阶段代码生成(WSCG,Whole Stage Code Generation) 数据结构 Tungsten 在…...
2023年总结的web前端学习路线分享(学习导读)
如果你打开了这篇文章,说明你是有兴趣想了解前端的这个行业的,以下是博主2023年总结的一些web前端的学习分享路线,如果你也想从事前端或者有这方面的想法的,请接着往下看! 前端发展前景 前端入门 巩固基础 前端工程…...
MyBatis学习笔记(十) —— 动态SQL
10、动态SQL MyBatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决拼接SQL语句字符串的痛点问题。 动态SQL: 1、if 标签:通过test属性中的表达式判断标签中的内容是否有效(是否会拼接到sql中…...
剑指 Offer 55 - II. 平衡二叉树
剑指 Offer 55 - II. 平衡二叉树 难度:easy\color{Green}{easy}easy 题目描述 输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。 示例 1: 给定二叉树 […...
一文吃透前端低代码的 “神仙生活”
今天来说说前端低代码有多幸福? 低代码是啥?顾名思义少写代码…… 这种情况下带来的幸福有:代码写得少,bug也就越少(所谓“少做少错”),因此开发环节的两大支柱性工作“赶需求”和“修bug”就…...
【深度学习】预训练语言模型-BERT
1.BERT简介 BERT是一种预训练语言模型(pre-trained language model, PLM),其全称是Bidirectional Encoder Representations from Transformers。下面从语言模型和预训练开始展开对预训练语言模型BERT的介绍。 1-1 语言模型 语言模型 …...
C++类的组合
C类的组合什么是类的组合初始化参数列表使用类的组合案例分析组合构造和析构顺序问题this指针基本用法和作用什么是类的组合 类的组合就是以另一个对象为数据成员,这种情况称为类的组合 1.优先使用类的组合,而不是继承 2.组合表达式的含义 一部分关系 初…...
2.伪随机数生成器(ctr_drbg)的配置与使用
零、随机数应用 生成盐,用于基于口令的密码 生成密钥,用于加密和认证 生成一次性整数Nonce,防止重放攻击 生成初始化向量IV 构成 种子,真随机数生成器的种子来源于物理现象 内部状态,种子用来初始化内部状态 一、真随机数和伪随机数 1.区别 随机数在安全技术中通常被用于…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
