【Go语言】接口类型(一)接口类型与接口的值

news2025/1/16 3:46:36

本文是介绍golang接口类型的第一篇,主要介绍接口类型与接口类型的值的相关概念。

1. 静态类型、动态类型、动态值

所谓的静态类型(即 static type),就是变量声明的时候的类型。

var age int   // int 是静态类型
var name string  // string 也是静态类型

它是你在编码时,肉眼可见的类型。
所谓的 动态类型(即 concrete type,也叫具体类型)是 程序运行时系统才能看见的类型。
这是什么意思呢?
我们都知道 空接口 可以承接什么问题类型的值,什么 int 呀,string 呀,都可以接收。
比如下面这几行代码

var i interface{}   
i = 18  
i = "Go编程"

第一行:我们在给 i 声明了 interface{} 类型,所以 i 的静态类型就是 interface{}
第二行:当我们给变量 i 赋一个 int 类型的值时,它的静态类型还是 interface{},这是不会变的,但是它的动态类型此时变成了 int 类型。
第三行:当我们给变量 i 赋一个 string 类型的值时,它的静态类型还是 interface{},它还是不会变,但是它的动态类型此时又变成了 string 类型。
从以上,可以知道,不管是 i=18 ,还是 i=“Go编程”,都是当程序运行到这里时,变量的类型,才发生了改变,这就是我们最开始所说的动态类型是程序运行时系统才能看见的类型

2. 接口类型的值

由于接口类型的值可以是任意一个实现该接口的类型值,所以除了具体的值,接口值还需要记录这个值的类型。也就是说接口值由类型(type)和值(value)组成。鉴于这两部分会根据存入的值不同而发送变化,我们称之为接口的动态类型动态值

type Mover interface {
    Move()
}

type Dog struct {
    Name string 
}

func (d *Dog) Move() {
    fmt.Println("狗在跑")
}

type Car struct {
    Brand string
}

func (c *Car) Move() {
    fmt.Println("汽车在跑")
}

var m Mover

image.png

fmt.Println(m==nil)  // true

此时将一个*Dog结构体赋值给m

m = &Dog{Name : "旺财"}

image.png
为接口变量m赋值一个*Car类型的值

m = new(Car)

image.png

fmt.Println(m==nil)  //false

此时仅仅是动态值是nil,动态类型不是nil,所以m不等于nil
接口值支持比较,当且仅当接口值的动态类型和动态值相等时相等

var (
    x Mover = new(Dog)
    y Mover = new(Car)
)

fmt.Println(x==y)   // false

Go 语言中,interface 的内部实现包含了 2 个字段,类型 T 和 值 V,interface 可以使用 == 或 != 比较。2 个 interface 相等有以下 2 种情况

  1. 两个 interface 均等于 nil(此时 V 和 T 都处于 unset 状态)
  2. 类型 T 相同,且对应的值 V 相等。

看下面的例子:

type Stu struct {
	Name string
}

type StuInt interface{}

func main() {
	var stu1, stu2 StuInt = &Stu{"Tom"}, &Stu{"Tom"}
	var stu3, stu4 StuInt = Stu{"Tom"}, Stu{"Tom"}
	fmt.Println(stu1 == stu2) // false
	fmt.Println(stu3 == stu4) // true
}

stu1 和 stu2 对应的类型是 *Stu,值是 Stu 结构体的地址,两个地址不同,因此结果为 false。
stu3 和 stu4 对应的类型是 Stu,值是 Stu 结构体,且各字段相等,因此结果为 true。

总结

  1. 接口类型的值包含动态类型和动态值。
  2. 接口类型的变量支持相互比较,只有当两个变量的动态类型和动态值都相等时两者才相等。
  3. 接口类型的变量支持和nil比较,只有当动态类型和动态值都为nil的时候两者才相等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1623194.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SSTV音频转图片

SSTV工具有很多,这里使用RX-SSTV慢扫描工具 下载安装 RX-SSTV解码软件 下载地址:https://www.qsl.net/on6mu/rxsstv.htm 一直点下一步,安装成功如下图: 虚拟声卡e2eSoft 由于SSTV工具是根据音频传递图片信息,正常解法需要一…

【动态规划】C++ dp子数组问题(最大/最长:环形/子数组和、乘积最大/为正数、单词拆分、子串)

文章目录 1. 前言 - 理解动态规划算法2. 例题最大子数组和 3. 算法题3.1_环形子数组的最大和3.2_乘积最大子数组3.3_乘积为正数的最长子数组长度3.4_等差数列划分3.5_最长湍流子数组3.6_单词拆分467.环绕字符串中唯一的子字符串 1. 前言 - 理解动态规划算法 关于 动态规划的理…

chrome 浏览器 f12 如何查看 websocket 消息?

1. 打开目标页面 2. f12--》网络--》WS,然后刷新页面( 如果不刷页面,就会看不到 websocket 请求,因为 websocket 是长连接,页面加载后只发出一次连接请求,不像 http 接口,不用刷新页面,待会儿也…

常见UI设计模式有哪些?从小白到资深必学

通过了解如何以及何时使用,每种 UI 设计模式都有其特定的目的,可以创建一个一致高效的界面。UI 设计模式为用户界面设计者提供了一种通用语言,并为网站和应用程序的用户提供了一致性。本指南,即时设计总结了 UI 设计模式和 UI 设计…

百种提权及手段一览系列第5集

特权升级的危险是显而易见的。通过提升权限,攻击者可以绕过网络安全措施,从而损害数据完整性、机密性和系统可用性。对于组织而言,这可能会导致数据泄露、系统停机以及潜在的法律和声誉后果。识别权限升级的迹象并部署预防性网络安全措施对于…

【团体程序设计天梯赛 往年关键真题 详细分析完整AC代码】L2-009 抢红包(排序) L2-010 排座位 (dfs)

【团体程序设计天梯赛 往年关键真题 详细分析&完整AC代码】搞懂了赛场上拿下就稳 【团体程序设计天梯赛 往年关键真题 25分题合集 详细分析&完整AC代码】(L2-001 - L2-024)搞懂了赛场上拿下就稳了 【团体程序设计天梯赛 往年关键真题 25分题合…

Vue2学习笔记(尚硅谷天禹老师)

目录 一、入门案例 二、模板语法 三、数据绑定 四、el和data的两种写法 五、MVVM模型 六、Object.defineproperty方法 七、Vue中响应式原理 八、数据代理 九、methods配置项 十、Vue中的事件处理 十一、Vue中的键盘事件 十二、计算属性 十三、监视属性watch 十四、绑定Class样式…

《系统架构设计师教程(第2版)》第10章-软件架构的演化和维护-01-软件架构演化概述

文章目录 1. 演化的重要性2. 架构演化示例 教材中,本节名为:“软件架构演化和定义的关系” 1. 演化的重要性 演化目的:维持软件架构自身的有用性 为什么说,软件架构是演化来的,而不是设计来的? 软件架构的…

N元语言模型

第1关:预测句子概率 任务描述 本关任务:利用二元语言模型计算句子的概率 相关知识 为了完成本关任务,你需要掌握:1.条件概率计算方式。 2.二元语言模型相关知识。 条件概率计算公式 条件概率是指事件A在事件B发生的条件下发…

麒麟龙芯loongarch64 electron 打包deb包

在麒麟龙芯(loongarch64)电脑上 使用electron 开发桌面应用。之前用electron-packager 打包出来的是文件夹 是 unpack 包。现在需要打包deb包,依据开发指南开始打包。 在项目文件夹下 打开终端 输入 npm run packager 先打包unpack包 然后…

AIGC算法3:Attention及其变体

1.Attention Attention是Transformer的核心部分,Attention机制帮助模型进行信息筛选,通过Q,K,V,对信息进行加工 1.1 attention计算公式 Attention ⁡ ( Q , K , V ) softmax ⁡ ( Q K T d k ) V \operatorname{Attention}(Q, K…

Fisher 准则分类

目录 一、什么是Fisher 准则 二、具体实例 三、代码实现 四、结果 一、什么是Fisher 准则 Fisher准则,即Fisher判别准则(Fisher Discriminant Criterion),是统计学和机器学习中常用的一种分类方法,由统计学家罗纳…

【golang学习之旅】Go 的基本数据类型

系列文章 【golang学习之旅】报错:a declared but not used 目录 系列文章总览布尔型(bool)字符串型(string)整数型(int、uint、byte、rune)浮点型(float32、float64)复…

网络安全之防范钓鱼邮件

随着互联网的快速发展,新的网络攻击形式“网络钓鱼”呈现逐年上升的趋势,利用网络钓鱼进行欺骗的行为越来越猖獗,对互联网的安全威胁越来越大。网络钓鱼最常见的欺骗方式就是向目标群体发送钓鱼邮件,而邮件标题和内容,…

类的六个构造函数相关干货

构造函数 特点 1.名字与类名相同 2.无返回值 3.对象实例化的时候编译器自动调用这个函数 4.构造函数可以重载(无参构造函数,拷贝构造等) 5.如果类中没有显式定义构造函数(深拷贝),则编译器会自动生成一个…

OpenSPG v0.0.3 发布,新增大模型统一知识抽取图谱可视化

基于非结构化文档的知识构建一直是知识图谱大规模落地的关键难题之一,4 月 23 日,OpenSPG 发布 v0.0.3 版本,正式发布了大模型统一知识抽取功能,可大幅降低领域知识图谱的构建成本。还可用于增强大模型缓解幻觉并提升稳定性&#…

Spring Boot中判断轨迹数据是否经过设置的打卡点,且在PGSQL中把点拼接成线,判断某个点是否在线上或在线的50米范围内

问题描述 轨迹数据判断是否经过打卡点,轨迹数据太多,循环判断的话非常消耗内存。解决办法只需要把所有轨迹数据点拼成了一条线,然后只需要循环打卡点即可,打卡点不多,一般不会超过100个,如果多的话&#x…

C++高级特性:异常概念与处理机制(十四)

1、异常的基本概念 异常:是指在程序运行的过程中发生的一些异常事件(如:除数为0,数组下标越界,栈溢出,访问非法内存等) C的异常机制相比C语言的异常处理: 函数的返回值可以忽略&…

C++ | Leetcode C++题解之第41题缺失的第一个正数

题目&#xff1a; 题解&#xff1a; class Solution { public:int firstMissingPositive(vector<int>& nums) {int n nums.size();for (int i 0; i < n; i) {while (nums[i] > 0 && nums[i] < n && nums[nums[i] - 1] ! nums[i]) {swap(…

助力实现更可持续未来的智能解决方案:AI如何改变世界

人工智能已然成为今年的热门话题。由于生成式AI应用的快速采用&#xff0c;新闻头条充斥着有关AI如何彻底改变我们的政策制定、就业和经济走向的预测。您知道AI也是我们应对各种可持续发展挑战的先锋吗&#xff1f;AI通过分析大量数据&#xff0c;并提供有用的见解和工具&#…