文章目录

  • 1.出乎意料的比较结果
  • 2.类型不等值相等
  • 3.类型相等值不等
  • 4.回首掏
  • 5.小结

1.出乎意料的比较结果

首先看一段代码:

func main() {s := "redigo: nil returned"err1 := errors.New(s)err2 := errors.New(s)if err1 == err2 {fmt.Println("err is equal")} else {fmt.Println("err is not equal")}
}

对两个相同字符串生成的 error 进行比较,结果如何呢?很多人可能和我一样,认为两个 error 变量是相等的,但实际上却不相等。输出结果:

err is not equal

为什么呢?这就需要我们知道接口变量相等比较到底比较了那些东西。

一个变量的两大基本属性就是"类型+值",接口变量也不例外。所以我们在比较接口变量是否相等时,如果"类型+值"二者都相等,那么才相等。

2.类型不等值相等

首先看一个接口变量所表示的值相等但类型不等的例子。

func main() {var ifc1 interface{} = int(1)var ifc2 interface{} = int64(1)if ifc1 == ifc2 {fmt.Println("err is equal")} else {fmt.Println("err is not equal")}fmt.Printf("%T %T %v %v\n", ifc1, ifc2, ifc1, ifc2)
}

定义了两个空接口类型变量 ifc1 和 ifc2,二者代表的真实值均是 1,但是类型却不相等,所以二等并不相等。

运行输出:

err is not equal
int int64 1 1

3.类型相等值不等

再看一个接口变量所表示的类型相等但值不等的例子。

func main() {var ifc1 interface{} = int(1)var ifc2 interface{} = int(2)if ifc1 == ifc2 {fmt.Println("err is equal")} else {fmt.Println("err is not equal")}fmt.Printf("%T %T %v %v\n", ifc1, ifc2, ifc1, ifc2)
}

因为两个空接口类型变量 ifc1 和 ifc2 代表的值不等,尽管二者所代表的类型均是 int,但是二者仍是不等的。

err is not equal
int int 1 2

4.回首掏

再回到最开始两个 error 变量相比较,既然不相等,那么说明其代表的值或类型至少有一个不相等。

眼睛看到的,并不一定是真相,尽管我们传的字符串是同一个。最终赋给 error 接口变量的值是 errors.New() 函数返回的东西,我们在 Golang 标准库 errors/errors.go 中可以找到 errors.New() 的定义。

// New returns an error that formats as the given text.
// Each call to New returns a distinct error value even if the text is identical.
func New(text string) error {return &errorString{text}
}// errorString is a trivial implementation of error.
type errorString struct {s string
}func (e *errorString) Error() string {return e.s
}

可以看到 errors.New() 每次返回的是结构体 errorString 变量的地址,每一次返回的都是新值,所以接口变量 err1 和 err2 存储的值并不相等,所以二者并不相等。

5.小结

当我们判断两个接口变量知否相等时,要注意接口变量所表示的具体类型和值均相等时才会相等,不要被表象迷惑,写出错误的代码。

Golang 接口相等比较注意要点相关推荐

  1. 雄兔脚扑朔,雌兔眼迷离;双兔傍地走,安能辨我是雄雌?——golang接口的概念

    古有花木兰替父从军,安能识我是女郎?今有golang接口隐式实现.对于一个具体的类型,无须声明它实现了哪些接口,只要提供接口所必需的方法即可. 因为golang是我新学的语言,我们先看看其他语言中接口 ...

  2. golang 接口类型 interface 简介

    目录 1. Go 语言与鸭子类型的关系 2. 值接收者和指针接收者的区别 方法 值接收者和指针接收者 两者分别在何时使用 3. iface 和 eface 的区别是什么 4. 接口的动态类型和动态值 ...

  3. golang 接口_「实战」助力数据库开发之接口篇 - Golang 连接 Greenplum

    Greenplum 作为一款强大的 HTAP 数据库,针对大多数流行语言都有相应的连接库.大部分均是与 PostgreSQL 采用相同的接口,但是也有部分接口是 Greenplum 专门优化后用于自身 ...

  4. golang 接口格式

    package main import "fmt" type Human struct { name string age int phone string } type Stud ...

  5. Golang——接口、多态、接口继承与转换、空接口、类型断言

    接口是一种规范与标准,只是规定了要做哪些事情.但是具体怎么做,是实现接口的类去做的,接口只是把所有具有共性的方法定义在一起. 接口存在的意义就是用来定义规范,用来做功能的拓展 接口最大的好处是可以实现 ...

  6. golang 接口类型 interface 简介使用

    1. Go 语言与鸭子类型的关系 先直接来看维基百科里的定义: If it looks like a duck, swims like a duck, and quacks like a duck, ...

  7. golang 接口的底层实现

    Golang将interface作为一种类型,并且不依赖继承,而是以一种类似于duck-typing的实现.所谓duck-typing,是一种动态类型风格:当一个obj走起来像鸭子.游泳起来像鸭子.叫 ...

  8. 【Golang 接口自动化05】使用yml管理自动化用例

    我们在前面几篇文章中学习怎么发送数据请求,怎么处理解析接口返回的结果,接下来我们一起来学习怎么进行测试用例管理,今天我们介绍的是使用yml文件进行用例管理,所以首先我们一起来了解一下YAML和它的简单 ...

  9. golang 接口_「Golang系列」 深入理解Golang Empty Interface (空接口)

    空接口可用于保存任何数据,它可以是一个有用的参数,因为它可以使用任何类型. 要理解空接口如何工作以及如何保存任何类型,我们首先应该理解名称背后的概念. 接口 这是Jordan Oreilli对空接口的 ...

最新文章

  1. 【python】用numpy随机生成一元(多元)数据;如线性、指数、三角函数,或者多种样式结合
  2. Windows 11 用户“怒了” :微软发推炫耀 3D 海龟表情包引争议
  3. src is not broadcastable to dst, but they have the same number of elements
  4. Python 输入输出
  5. a^logbx=x^logba
  6. Laravel新建对象的方法:make resolve 辅助函数app()
  7. php如何防止超发,PHP+redis实现的限制抢购防止商品超发功能详解
  8. 递归入门 斐波那契数列
  9. leetcode409. 最长回文串
  10. DNS练习之反向解析
  11. Scrum与项目管理亲体验
  12. Firefox附加在合谋表演,谁跟踪你上网
  13. Postgre中的 select for update 和 select for update nowait
  14. python3.7安装pyltp出错_安装pyltp遇到的问题及解决办法
  15. table表单的制作
  16. 【论文笔记--FORCE】Progressive Skeletonization: Trimming more fat from a networkat initialization
  17. 图神经网络七日打卡营 Day 01 什么是非欧空间
  18. css 侧栏跟随_简单代码实现智能侧边栏跟随固定浮动的效果
  19. PDF/OCR识别提取工具:Readiris Pro 17 for Mac
  20. 【ThreeJS基础教程-初识Threejs】1.6各种各样的几何体

热门文章

  1. JMockit常用操作
  2. [Luogu1462]通往奥格瑞玛的道路
  3. 王彪20162321 2017-2018程序设计与数据结构-第二学期-第一周学习总结
  4. 最长递增子序列 动态规划
  5. KVM virtio bug整理
  6. [CTO札记]电纸书,将成为教学、阅读潮流
  7. oracle安装过程中内核参数详解
  8. java的继承和访问_Java基础篇:如何解决成员的访问和继承?
  9. SpringBoot 之多个过滤器(Filter) ,监听器(Listener),切面(AOP),拦截器(Interceptor)的指定排序问题总结篇
  10. [swift] LeetCode 234. Palindrome Linked List