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

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

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

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

go 复制代码
var age int   // int 是静态类型
var name string  // string 也是静态类型

它是你在编码时,肉眼可见的类型。

所谓的 动态类型 (即 concrete type,也叫具体类型)是 程序运行时系统才能看见的类型。

这是什么意思呢?

我们都知道 空接口 可以承接什么问题类型的值,什么 int 呀,string 呀,都可以接收。

比如下面这几行代码

go 复制代码
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)组成 。鉴于这两部分会根据存入的值不同而发送变化,我们称之为接口的动态类型动态值

go 复制代码
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("汽车在跑")
}
go 复制代码
var m Mover
go 复制代码
fmt.Println(m==nil)  // true

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

go 复制代码
m = &Dog{Name : "旺财"}

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

go 复制代码
m = new(Car)
go 复制代码
fmt.Println(m==nil)  //false

此时仅仅是动态值是nil,动态类型不是nil,所以m不等于nil

接口值支持比较,当且仅当接口值的动态类型和动态值相等时相等

go 复制代码
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 相等。

看下面的例子:

cpp 复制代码
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的时候两者才相等。
相关推荐
摇滚侠2 小时前
Spring Boot 3零基础教程,IOC容器中组件的注册,笔记08
spring boot·笔记·后端
rit84324994 小时前
基于MATLAB的模糊图像复原
开发语言·matlab
fie88894 小时前
基于MATLAB的声呐图像特征提取与显示
开发语言·人工智能
程序员小凯4 小时前
Spring Boot测试框架详解
java·spring boot·后端
_extraordinary_5 小时前
Java SpringMVC(二) --- 响应,综合性练习
java·开发语言
你的人类朋友5 小时前
什么是断言?
前端·后端·安全
@。1246 小时前
对于灰度发布(金丝雀发布)的了解
开发语言·前端
程序员小凯6 小时前
Spring Boot缓存机制详解
spring boot·后端·缓存
i学长的猫6 小时前
Ruby on Rails 从0 开始入门到进阶到高级 - 10分钟速通版
后端·ruby on rails·ruby
用户21411832636027 小时前
别再为 Claude 付费!Codex + 免费模型 + cc-switch,多场景 AI 编程全搞定
后端