golang中的空接口使用详解


Posted in Python onMarch 30, 2021

1、空接口

Golang 中的接口可以不定义任何方法,没有定义任何方法的接口就是空接口。空接口表示,没有任何约束,因此任何类型变量都可以实现空接口。空接口在实际项目中用的是非常多的,用空接口可以表示任意数据类型

func main() {
// 定义一个空接口 x, x 变量可以接收任意的数据类型
var x interface{}
s := "你好 golang"
x = s
fmt.Printf("type:%T value:%v\n", x, x)
i := 100
x = i
fmt.Printf("type:%T value:%v\n", x, x)
b := true
x = b
fmt

1 、空接口作为函数的参数: 使用空接口实现可以接收任意类型的函数参数

// 空接口作为函数参数
func show(a interface{}) {
fmt.Printf("type:%T value:%v\n", a, a)
}

2 、map 的值 实现空接口: 使用空接口实现可以保存任意值的字典

// 空接口作为 map 值
var studentInfo = make(map[string]interface{})
studentInfo["name"] = "张三"
studentInfo["age"] = 18
studentInfo["married"] = false
fmt.Println(studentInfo

3 、切片实现空接口

var slice = []interface{}{"张三", 20, true, 32.2}
fmt.Println(slice)

2、类型断言

一个接口的值(简称接口值)是由一个具体类型和具体类型的值两部分组成的。这两部分分

别称为接口的动态类型和动态值。

如果我们想要判断空接口中值的类型,那么这个时候就可以使用类型断言,其语法格式:x.(T)

其中:

• x : 表示类型为 interface{}的变量

• T : 表示断言 x 可能是的类型。

该语法返回两个参数,第一个参数是 x 转化为 T 类型后的变量,第二个值是一个布尔值,若

为 true 则表示断言成功,为 false 则表示断言失败

例如:

func main() {
var x interface{}
x = "Hello golnag"
v, ok := x.(string)
if ok {
fmt.Println(v)
} else {
fmt.Println("类型断言失败")
}
}

上面的示例中如果要断言多次就需要写多个 if 判断,这个时候我们可以使用 switch 语句来

实现:

注意:类型.(type)只能结合 switch 语句使用

func justifyType(x interface{}) {
switch v := x.(type) {
case string:
fmt.Printf("x is a string,value is %v\n", v)
case int:
fmt.Printf("x is a int is %v\n", v)
case bool:
fmt.Printf("x is a bool is %v\n", v)
default:
fmt.Println("unsupport type!")
}
}

因为空接口可以存储任意类型值的特点,所以空接口在 Go 语言中的使用十分广泛。

关于接口需要注意的是: :只有当有两个或两个以上的具体类型必须以相同的方式进行处理时

才需要定义接口。不要为了接口而写接口,那样只会增加不必要的抽象,导致不必要的运行

时损耗。

3、结构体值接收者和指针接收者实现接口的区别

值接收者:

如果结构体中的方法是值接收者,那么实例化后的结构体值类型和结构体指针类型都可以赋

值给接口变量

package main
import "fmt"
type Usb interface {
Start()
Stop()
}
type Phone struct {
Name string
}
func (p Phone) Start() {
fmt.Println(p.Name, "开始工作")
}
func (p Phone) Stop() {
fmt.Println("phone 停止")
}
func main() {
phone1 := Phone{
Name: "小米手机",
}
var p1 Usb = phone1 //phone1 实现了 Usb 接口 phone1 是 Phone 类型
p1.Start() //小米手机 开始工作
phone2 := &Phone{
Name: "苹果手机",
}
var p2 Usb = phone2 //phone2 实现了 Usb 接口 phone2 是 *Phone 类型
p2.Start() //苹果手机 开始工作
}

指针接收者:

如果结构体中的方法是指针接收者,那么实例化后结构体指针类型都可以赋值给接口变量,

结构体值类型没法赋值给接口变量

package main
import "fmt"
type Usb interface {
Start()
Stop()
}
type Phone struct {
Name string
}
func (p *Phone) Start() {
fmt.Println(p.Name, "开始工作")
}
func (p *Phone) Stop() {
fmt.Println("phone 停止")
}
func main() {
/*
错误写法
phone1 := Phone{
Name: "小米手机",
}
var p1 Usb = phone1
p1.Start()
*/
//正确写法
phone2 := &Phone{
Name: "苹果手机",
}
var p2 Usb = phone2 //phone2 实现了 Usb 接口 phone2 是 *Phone 类型
p2.Start() //苹果手机 开始工作
}

4、一个结构体实现多个接口

Golang 中一个结构体也可以实现多个接口

package main
import "fmt"
type AInterface interface {
GetInfo() string
}
type BInterface interface {
SetInfo(string, int)
}
type People struct {
Name string
Age int
}
func (p People) GetInfo() string {
return fmt.Sprintf("姓名:%v 年龄:%d", p.Name, p.Age)
}
func (p *People) SetInfo(name string, age int) {
p.Name = name
p.Age = age
}
func main() {
var people = &People{
Name: "张三",
Age: 20,
}
// people 实现了 AInterface 和 BInterface
var p1 AInterface = people
var p2 BInterface = people
fmt.Println(p1.GetInfo())
p2.SetInfo("李四", 30)
fmt.Println(p1.GetInfo())
}

5、接口嵌套

接口与接口间可以通过嵌套创造出新的接口

package main
import "fmt"
type SayInterface interface {
say()
}
type MoveInterface interface {
move()
}
// 接口嵌套
type Animal interface {
SayInterface
MoveInterface
}
type Cat struct {
name string
}
func (c Cat) say() {
fmt.Println("喵喵喵")
}
func (c Cat) move() {
fmt.Println("猫会动")
}
func main() {
var x Animal
x = Cat{name: "花花"}
x.move()
x.say()
}

6、Golang中空接口和类型断言使用细节

使用空接口定义一个map类型的数据,其数据中是切片或者结构体,其通过索引拿到对应切片内容的值,出现错误,必须通过类型断言的形式拿到对应的数据,结构体同理,案例如下:

package main

import "fmt"

type Address struct {
 Name string
 Phone int
}

// Golang中空接口和类型断言使用细节
func main() {

 var userinfo = make(map[string]interface{})
 userinfo["username"] = "张三"
 userinfo["age"] = 20
 userinfo["hobby"] = []string{"睡觉", "吃饭"}

 fmt.Println(userinfo["age"])
 fmt.Println(userinfo["hobby"])

 // fmt.Println(userinfo["hobby"][1]) //interface {} does not support indexing

 var address = Address{
 Name: "李四",
 Phone: 1521242141,
 }
 fmt.Println(address.Name) //李四

 userinfo["address"] = address

 fmt.Println(userinfo["address"]) //{李四 1521242141}

 // var name = userinfo["address"].Name //type interface {} is interface with no methods
 // fmt.Println(name)

 hobby2, _ := userinfo["hobby"].([]string)

 fmt.Println(hobby2[1]) //吃饭

 address2, _ := userinfo["address"].(Address)
 fmt.Println(address2.Name, address2.Phone) //李四 1521242141

}

到此这篇关于golang中的空接口使用的文章就介绍到这了,更多相关golang空接口使用内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
在Python的Django框架下使用django-tagging的教程
May 30 Python
Python向日志输出中添加上下文信息
May 24 Python
Tensorflow实现AlexNet卷积神经网络及运算时间评测
May 24 Python
python实现windows壁纸定期更换功能
Jan 21 Python
pytorch方法测试详解——归一化(BatchNorm2d)
Jan 15 Python
使用Tensorflow实现可视化中间层和卷积层
Jan 24 Python
基于spring boot 日志(logback)报错的解决方式
Feb 20 Python
解决pyPdf和pyPdf2在合并pdf时出现异常的问题
Apr 03 Python
Python第三方包之DingDingBot钉钉机器人
Apr 09 Python
aws 通过boto3 python脚本打pach的实现方法
May 10 Python
python tkiner实现 一个小小的图片翻页功能的示例代码
Jun 24 Python
Python Tkinter实例——模拟掷骰子
Oct 24 Python
在 Golang 中实现 Cache::remember 方法详解
Mar 30 #Python
Python离线安装openpyxl模块的步骤
解决Jupyter-notebook不弹出默认浏览器的问题
Python爬取科目四考试题库的方法实现
Python如何使用logging为Flask增加logid
Mar 30 #Python
如何在Python中创建二叉树
pycharm2021激活码使用教程(永久激活亲测可用)
You might like
全国FM电台频率大全 - 3 河北省
2020/03/11 无线电
浅析php中三个等号(===)和两个等号(==)的区别
2013/08/06 PHP
yii2实现 "上一篇,下一篇" 功能的代码实例
2017/02/04 PHP
Docker搭建自己的PHP开发环境
2018/02/24 PHP
Yii框架函数简单用法分析
2019/09/09 PHP
redis+php实现微博(二)发布与关注功能详解
2019/09/23 PHP
laravel http 自定义公共验证和响应的方法
2019/09/29 PHP
javascript 通用简单的table选项卡实现
2010/05/07 Javascript
JS+css 图片自动缩放自适应大小
2013/08/08 Javascript
JavaScript检测上传文件大小的方法
2015/07/22 Javascript
js实现网页图片延时加载 提升网页打开速度
2016/01/26 Javascript
微信小程序 生命周期详解
2016/10/12 Javascript
AngularJS日期格式化常见操作实例分析
2018/05/17 Javascript
cnpm加速Angular项目创建的方法
2018/09/07 Javascript
在Vue-cli里应用Vuex的state和mutations方法
2018/09/16 Javascript
详解关于Vuex的action传入多个参数的问题
2019/02/22 Javascript
Vue常用传值方式、父传子、子传父及非父子实例分析
2020/02/24 Javascript
[54:51]Ti4 冒泡赛第二轮LGD vs C9 3
2014/07/14 DOTA
[04:14]从西雅图到上海——玩家自制DOTA2主题歌曲应援TI9
2019/07/11 DOTA
利用python爬取软考试题之ip自动代理
2017/03/28 Python
python先序遍历二叉树问题
2017/11/10 Python
解决python给列表里添加字典时被最后一个覆盖的问题
2019/01/21 Python
浅谈Python爬虫基本套路
2019/03/25 Python
利用pyinstaller打包exe文件的基本教程
2019/05/02 Python
Python 200行代码实现一个滑动验证码过程详解
2019/07/11 Python
使用Python快乐学数学Github万星神器Manim简介
2019/08/07 Python
详解Python中pyautogui库的最全使用方法
2020/04/01 Python
Python多线程正确用法实例解析
2020/05/30 Python
MoviePy简介及Python视频剪辑自动化
2020/12/18 Python
有机童装:Toby Tiger
2018/05/23 全球购物
美国婚礼装饰和活动用品批发供应商:Event Decor Direct
2018/10/12 全球购物
五年级科学教学反思
2014/02/05 职场文书
家长会主持词开场白
2014/03/18 职场文书
班主任个人工作反思
2014/04/28 职场文书
领导干部作风整顿个人剖析材料
2014/10/11 职场文书
高三毕业感言
2015/07/30 职场文书