golang学习笔记——接口interfaces

文章目录

  • Go 语言接口
  • 例子
  • 空接口
    • 空接口的定义
    • 空接口的应用
      • 空接口作为函数的参数
      • 空接口作为map的值
  • 类型断言
    • 接口值
  • 类型断言例子001
  • 类型断言例子002
  • 类型断言例子003
  • 巩固练习

Go 语言接口

接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节。
interface是一组method的集合,是duck-type programming的一种体现。接口做的事情就像是定义一个协议(规则),只要一台机器有洗衣服和甩干的功能,我就称它为洗衣机。不关心属性(数据),只关心行为(方法)。

为了保护你的Go语言职业生涯,请牢记接口(interface)是一种类型。

interface类型可以定义一组方法,但是不需要实现。并且接口(interface)不能包含任何变量

在这里插入图片描述
实例

/* 定义接口 */
type interface_name interface {method_name1 [return_type]method_name2 [return_type]method_name3 [return_type]...method_namen [return_type]
}/* 定义结构体 */
type struct_name struct {/* variables */
}/* 实现接口方法 */
func (struct_name_variable struct_name) method_name1() [return_type] {/* 方法实现 */
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {/* 方法实现*/
}

例子

Go 中的接口是满足隐式实现的(这一点是非常坑人的,建议阅读 Go语言令人厌恶的设计)。 Go 不提供用于实现接口的关键字。

package mainimport ("fmt""math"
)func main() {var s Shape = Square{3}printInformation(s)c := Circle{6}printInformation(c)
}//打印面积和周长
func printInformation(s Shape) {fmt.Printf("%T\n", s)fmt.Println("Area: ", s.Area())fmt.Println("Perimeter:", s.Perimeter())fmt.Println()
}//---Shape 形状---
type Shape interface {//周长Perimeter() float64//面积Area() float64
}//---Square 正方形---
type Square struct {size float64
}func (s Square) Area() float64 {return s.size * s.size
}func (s Square) Perimeter() float64 {return s.size * 4
}//---Circle 圆形---
type Circle struct {radius float64
}func (c Circle) Area() float64 {return math.Pi * c.radius * c.radius
}func (c Circle) Perimeter() float64 {return 2 * math.Pi * c.radius
}

输出

main.Square
Area:  9
Perimeter: 12main.Circle
Area:  113.0973
Perimeter: 37.6991

空接口

空接口的定义

空接口是指没有定义任何方法的接口。因此任何类型都实现了空接口。

空接口类型的变量可以存储任意类型的变量。

func main() {// 定义一个空接口xvar x interface{}s := "pprof.cn"x = sfmt.Printf("type:%T value:%v\n", x, x)i := 100x = ifmt.Printf("type:%T value:%v\n", x, x)b := truex = bfmt.Printf("type:%T value:%v\n", x, x)
}

空接口的应用

空接口作为函数的参数

使用空接口实现可以接收任意类型的函数参数。

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

空接口作为map的值

使用空接口实现可以保存任意值的字典。

// 空接口作为map值var studentInfo = make(map[string]interface{})studentInfo["name"] = "李白"studentInfo["age"] = 18studentInfo["married"] = falsefmt.Println(studentInfo) 

类型断言

空接口可以存储任意类型的值,那我们如何获取其存储的具体数据呢?

接口值

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

我们来看一个具体的例子:

var w io.Writer
w = os.Stdout
w = new(bytes.Buffer)
w = nil 

请看下图分解:
在这里插入图片描述
想要判断空接口中的值这个时候就可以使用类型断言,其语法格式:

    x.(T) 

其中:

    x:表示类型为interface{}的变量T:表示断言x可能是的类型。

该语法返回两个参数,第一个参数是x转化为T类型后的变量,第二个值是一个布尔值,若为true则表示断言成功,为false则表示断言失败。

举个例子:

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

上面的示例中如果要断言多次就需要写多个if判断,这个时候我们可以使用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语言中的使用十分广泛。

关于接口需要注意的是,只有当有两个或两个以上的具体类型必须以相同的方式进行处理时才需要定义接口。不要为了接口而写接口,那样只会增加不必要的抽象,导致不必要的运行时损耗。

类型断言例子001

类型断言也可以判断指针类型

package mainimport "fmt"func main() {var n1 int32 = 30var n2 string = "tomcat"n3 := falsestu1 := Student{}stu2 := &Student{}justifyType(n1,n2,n3,stu1,stu2)
}type Student struct {}func justifyType(items ...interface{}) {for index, x := range items {switch v := x.(type) {case string:fmt.Printf("第%v个参数是 string 类型,值是 %v\n",index,v)case int:fmt.Printf("第%v个参数是 int 类型,值是 %v\n",index,v)case bool:fmt.Printf("第%v个参数是 bool 类型,值是 %v\n",index,v)case Student:fmt.Printf("第%v个参数是 Student 类型,值是 %v\n",index,v)case *Student:fmt.Printf("第%v个参数是 *Student 类型,值是 %v\n",index,v)default:fmt.Println("unsupport type!")}}
} 

类型断言例子002

package mainimport "fmt"func main() {var i interface{} = "Hello, World"str, ok := i.(string)if ok {fmt.Printf("'%s' is a string\n", str)} else {fmt.Println("conversion failed")}
}

类型断言例子003

给Phone结构体一个特有的方法Call(),当Usb接口接收的是Phone变量时,还需要调用call方法

package mainimport "fmt"func main() {//定义一个usb接口数组,可以存放Phone和Camera的结构体变量// 这里就体现出多态数组var usbArr [3]UsbusbArr[0] = Phone{"vivo"}usbArr[1] = Phone{"小米"}usbArr[2] = Camera{"惠普"}//遍历usbArrvar computer Computerfor _, v := range usbArr {computer.Working(v)}
}type Usb interface {Start()Stop()
}type Camera struct {name string		
}type Phone struct {name string
}type Computer struct {name string
}func (c Camera) Start() {fmt.Println("相机开始工作...")
}func (c Camera) Stop() {fmt.Println("相机停止工作...")
}func (p Phone) Start() {fmt.Printf("%s 手机开始工作...\n", p.name )
}func (p Phone) Stop() {fmt.Printf("%s 手机停止工作...\n", p.name )
}func (p Phone) Call() {fmt.Println("手机 打电话")
}func (computer Computer) Working(usb Usb) {usb.Start()if phone, ok := usb.(Phone); ok {phone.Call()}usb.Stop()
}

巩固练习

  1. 在Go语言中,接口是什么?请解释其含义。
  2. 如何定义一个接口?解释接口定义的基本语法。
  3. Go语言中的接口实现是如何工作的?请详细解释。
  4. 什么是空接口?它有什么用途?
  5. 能否给出一些使用接口的例子?这些例子中接口的作用是什么?
  6. Go语言不同接口、声明了同名方法,怎么解决问题?

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

qt-C++笔记之两个窗口ui的交互

qt-C笔记之两个窗口ui的交互 code review! 文章目录 qt-C笔记之两个窗口ui的交互0.运行1.文件结构2.先创建widget项目,搞一个窗口ui出来3.项目添加第二个widget窗口出来4.补充代码4.1.qt_widget_interaction.pro4.2.main.cpp4.3.widget.h4.4.widget.cpp4.5.second…

免费稳定几乎无门槛,我的ChartGPT助手免费分享给你

公众号「架构成长指南」,专注于生产实践、云原生、分布式系统、大数据技术分享。 概述 ChatGPT想必大家应该都不陌生了,大部分人或多或少都接触了,好多应该都是通过openAi的官方进行使用的,这个门槛对大部分人有点高,…

shell脚本学习笔记07

如何让shell实现 可选择性执行 的功能 用了while进行循环,是死循环,在循环时,使用case进行使用哪个脚本进行执行。使用clear进行每一次操作前的清屏,eof代表输入这个会显示目录。read用来读取输入的值,如果不输入值不会…

【教学类-06-06】20231118 (55格版)X以内加法、减法、加减混合题

背景需求 1、长期做手工制作,常规管理难以控制 优势: 1、幼儿创作热情高涨,发明的新玩具多 2、互助观摩,进一步模仿、创作作品 3、互动游戏兴趣浓厚,语言交流踊跃, 劣势: 1、纸条碎片多&…

ARM CoreLink CCN 互连总线介绍

NIC NOC CCI CMN CNN NI cmn-700 nic-700 ni-700 MLGB这都是啥玩意? 后期博文或视频将会更新这一系列。今天先温习一下CNN的概念,这是来自2014年的文章,然后稍微整理总结一番。 以下是正文… 现代主流和优质 ARM 片上系统 (SoC) 产品使用 CoreLink 缓存一致性网络 (CCN) 504…

ClientDateSet:Cannot perform this operation on a closed dataset

一、问题表现 Delphi 三层DataSnap,使用AlphaControls控件优化界面,一窗口编辑时,出现下列错误提示: 编译通过,该窗口中,重新显示数据,下图: 相关代码: procedure…

Django自动生成docs接口文档

1.创建Django项目 python manage.py startproject django20252.创建子应用 python manage.py startapp api3.安装依赖包 pip install coreapi4.创建urls.py from django.contrib import admin from django.urls import path, include from rest_framework import routers f…

数学建模值TOPSIS法及代码

TOPSIS法 TOPSIS法简称为优劣距离解法,是一种常见法综合评价方法,其能充分利用原始数据的信息,其结果能精确地反映各个评价方案之间的差距。 模型介绍 上篇文章谈到的层次分析法是有局限性的。比如评价的决策层不能太多,太多的…

PPT基础:合并形状

目录 合并形状功能详解合并形状使用文字转形状图表转形状 合并形状功能详解 形状:并不局限于ppt内给定的图形,也并不全是图形 (1)所在位置:选中图形后>>>形状格式>>>最左边 (2&#x…

关于爬虫中的hook(defineProperty,hook cookies, hook载荷数据,hookXHR)

关于爬虫中的hook: defineProperty var people {age: 19, }; var count20; console.log(people.age) // 参数:对象 属性名字 函数 Object.defineProperty(people, age, {get: function () {console.log(获取值!);return count;},// set: …

通信原理板块——纠错编码最小码距与纠错能力的计算

微信公众号上线,搜索公众号小灰灰的FPGA,关注可获取相关源码,定期更新有关FPGA的项目以及开源项目源码,包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 对纠错编码的最小码距d0与编码的检…

【C++】:模板的使用

目录 1、泛型编程 2、函数模板 2.1、函数模板概念 2.2、函数模板格式 2.3、函数模板的原理 2.4、函数模板的实例化 2.6、模板参数的匹配原则 3、类模板 3.1、 类模板的定义格式 3.2、 类模板的实例化 4、非类型模板参数 5、模板的特化 5.1、函数模板特化 5.2、类模…