空接口

空接口是指没有定义任何接口方法的接口。没有定义任何接口方法,意味着Go中的任意对象都可以实现空接口(因为没方法需要实现),任意对象都可以保存到空接口实例变量中

空接口的定义方式:

type empty_int interface {
}

通常会简写为type empty_int interface{}

更常见的,会直接使用interface{}作为一种类型,表示空接口。例如:

// 声明一个空接口实例
var i interface{}

再比如函数使用空接口类型参数:

func myfunc(i interface{})

在Go中很多地方都使用空接口类型的参数,用的最多的fmt中的Print类方法:

$ go doc fmt Println
func Println(a ...interface{}) (n int, err error)

空接口数据结构

可以定义一个空接口类型的array、slice、map、struct等,这样它们就可以用来存放任意类型的对象,因为任意类型都实现了空接口。

例如,创建一个空接口的slice:

package main

import "fmt"

func main() {
any := make([]interface{}, 5)
any[0] = 11
any[1] = "hello world"
any[2] = []int{11, 22, 33, 44}
for _, value := range any {
fmt.Println(value)
}
}

输出结果:

11
hello world
[11 22 33 44]
<nil>
<nil>

显然,通过空接口类型,Go也能像其它动态语言一样,在数据结构中存储任意类型的数据。

再比如,某个struct中,如果有一个字段想存储任意类型的数据,就可以将这个字段的类型设置为空接口:

type my_struct struct {
anything interface{}
anythings []interface{}
}

拷贝数据结构到空接口数据结构

前面解释了任意类型的对象都能赋值给空接口实例。

var any interface{}
any = "hello world"
any = 11

空接口是一种接口,它是一种指针类型的数据类型,虽然不严谨,但它确实保存了两个指针,一个是对象的类型(或iTable),一个是对象的值。所以上面的赋值过程是让空接口any保存各个数据对象的类型和对象的值。

换一种角度考虑,空接口有自己的内存布局方式:两个指针,占用两个机器字长。

Golang给的一个经典的示例:将某个slice中的数据拷贝到空接口slice中将报错。

package main

import "fmt"

func main() {
testSlice := []int{11,22,33,44} // 成功拷贝
var newSlice []int
newSlice = testSlice
fmt.Println(newSlice) // 拷贝失败
var any []interface{}
any = testSlice
fmt.Println(any)
}

这是因为每个空接口的内存布局都占用两个机器字长的内容。对于长度为N的空接口slice来说,它的每个元素都是以2机器字长为单元的连续空间,共占用N*2个机器字长的空间。

而普通的slice,例如上面的testSlice,它的每个元素是int类型的,int类型的内存布局和空接口不一样。

这些对象的内存布局在编译期间就已经确定好了,所以没法直接将不同内存布局的数据结构进行拷贝。

要想完成期待的拷贝,可以使用for-range的方式,将testSlice中的每个元素赋值给空接口slice的空接口元素:也就是一个个的空接口实例。

var any []interface{}
for _,value := range testSlice{
any = append(any,value)
}

这样,空接口Slice中的每个空接口实例都指向更底层的各个数据对象。而不是像前面错误的拷贝方式:每个空接口元素想要当作这些数据对象。

不仅空接口的Slice如此,其它包含空接口的数据结构,也都类似。

Go基础系列:空接口的更多相关文章

  1. Go基础系列:接口类型断言和type-switch

    接口类型探测:类型断言 接口实例中存储了实现接口的类型实例,类型的实例有两种:值类型实例和指针类型实例.在程序运行过程中,接口实例存储的实例类型可能会动态改变.例如: // ins是接口实例 var ...

  2. 夯实Java基础系列6:一文搞懂抽象类和接口,从基础到面试题,揭秘其本质区别!

    目录 抽象类介绍 为什么要用抽象类 一个抽象类小故事 一个抽象类小游戏 接口介绍 接口与类相似点: 接口与类的区别: 接口特性 抽象类和接口的区别 接口的使用: 接口最佳实践:设计模式中的工厂模式 接 ...

  3. 带你学够浪:Go语言基础系列 - 10分钟学方法和接口

    文章每周持续更新,原创不易,「三连」让更多人看到是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) 对于一般的语言使用者来说 ,20% 的语言特性就能够满 ...

  4. C#基础系列——一场风花雪月的邂逅:接口和抽象类

    前言:最近一个认识的朋友准备转行做编程,看他自己边看视频边学习,挺有干劲的.那天他问我接口和抽象类这两个东西,他说,既然它们如此相像, 我用抽象类就能解决的问题,又整个接口出来干嘛,这不是误导初学者吗 ...

  5. Go基础系列:Go接口

    接口用法简介 接口(interface)是一种类型,用来定义行为(方法). type Namer interface { my_method1() my_method2(para) my_method ...

  6. Java基础系列-ArrayList

    原创文章,转载请标注出处:<Java基础系列-ArrayList> 一.概述 ArrayList底层使用的是数组.是List的可变数组实现,这里的可变是针对List而言,而不是底层数组. ...

  7. JVM基础系列第5讲:字节码文件结构

    温馨提示:此篇文章长达两万字,图片50多张,内容非常多,建议收藏后再看. 前面我们说到 Java 虚拟机使用字节码实现了跨平台的愿景,无论什么系统,我们都可以使用 Java 虚拟机解释执行字节码文件. ...

  8. Spring基础系列-AOP源码分析

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9560803.html 一.概述 Spring的两大特性:IOC和AOP. AOP是面向切 ...

  9. 基础系列(6)—— C#类和对象

    一.类介绍       类(class)是C#类型中最基础的类型.类是一个数据结构,将状态(字段)和行为(方法和其他函数成员)组合在一个单元中.类提供了用于动态创建类实例的定义,也就是对象(objec ...

随机推荐

  1. SecureCRT两步验证自动登录脚本

    简介 用于解决 Google Authenticator 的两步验证登录.涉及到密码,不建议脚本保存到公共环境. 安装oathtool Mac $ brew install oath-toolkit ...

  2. cordova 问题汇总

    用chrome进行调试: https://jingyan.baidu.com/album/db55b609fde96d4ba30a2fa9.html?picindex=8 http://rensann ...

  3. Java 异常与反射 总结

    1.异常 异常,简单来说,就是一个程序执行过程中发生的不正常情况的事件.它发生在程序的运行期间,干扰了正常的指令流程.如果没有处理异常,那么出现异常之后,程序会停止运行.异常分为运行异常和非运行异常. ...

  4. (三)Javascript面向对象编程:非构造函数的继承

    Javascript面向对象编程:非构造函数的继承   这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现"继承". 今天是最后一个部分,介绍不使 ...

  5. 简析 __init__、__new__、__call__ 方法

    简析 __init__.__new__.__call__ 方法 任何事物都有一个从创建,被使用,再到消亡的过程,在程序语言面向对象编程模型中,对象也有相似的命运:创建.初始化.使 用.垃圾回收,不同的 ...

  6. 运维工具pssh和pdsh安装和使用

    1. pssh安装与使用 1.1 pssh安装 [root@server]# wget http://peak.telecommunity.com/dist/ez_setup.py [root@ser ...

  7. React了解

    根据博主  http://www.ruanyifeng.com/blog/2015/03/react.html  的几个Demo(https://github.com/ruanyf/react-dem ...

  8. QQ现状深度剖析:你还认为QQ已经被微信打败了吗?

    本文来自“人人都是产品经理”公众号作者栗栗粥的原创分享. 1.前言   移动端的时代里,微信占据了社交领域的半壁江山,不得不让人想起曾经PC时代里的王者“QQ”,微信的爆发和QQ的停滞让很多人认为微信 ...

  9. 110道python面试笔试题汇总,你能答对几道?

    数据分析系列教程插播一篇面试题教程,最近公众号新来了不少朋友,这几天不少粉丝留言说问我有没有python面试题,其实之前分享过一些面试题,今天统一再给大家分享一遍,也希望能帮助此时仍在找工作的同学,尽 ...

  10. SpringCache学习实践

    1. SpringCache学习实践 1.1. 引用 <dependency> <groupId>org.springframework.boot</groupId> ...