当前位置: 首页 > news >正文

Go语言基础之接口

Go语言基础之接口

  • 1.Go语言接口类型
  • 2.类型与接口的关系
    • 一个类型实现多个接口
    • 多种类型实现同一接口
  • 3.空接口
  • 4.类型断言

1.Go语言接口类型

每个接口类型由任意个方法签名组成,接口的定义格式如下:

type 接口类型名 interface{方法名1( 参数列表1 ) 返回值列表1方法名2( 参数列表2 ) 返回值列表2}

Go语言的接口在命名时,一般会在单词后面添加er,如有写操作的接口叫Writer,有关闭操作的接口叫closer等。接口名最好要能突出该接口的类型含义👕

举个例子,定义一个包含Write方法的Writer接口

type Writer interface{Write([]byte) error
}

实现接口的条件:

接口就是规定了一个需要实现的方法列表,在 Go 语言中一个类型只要实现了接口中规定的所有方法,那么我们就称它实现了这个接口。

我们定义的Singer接口类型,它包含一个Sing方法。

// Singer 接口
type Singer interface {Sing()
}

我们有一个Bird结构体类型如下:

type Bird struct {}

因为Singer接口只包含一个Sing方法,所以只需要给Bird结构体添加一个Sing方法就可以满足Singer接口的要求

接口的实现案例:

package mainimport "fmt"type Sayer interface {Say()
}type Cat struct{}func (c Cat) Say() {fmt.Println("喵喵喵~")
}type Dog struct{}func (d Dog) Say() {fmt.Println("汪汪汪~")
}// MakeHungry 饿肚子了...
func MakeHungry(s Sayer) {s.Say()
}func main() {var c CatMakeHungry(c) // 喵喵喵~var d DogMakeHungry(d)  // 汪汪汪~
}

2.类型与接口的关系

一个类型实现多个接口

一个类型可以同时实现多个接口,而接口间彼此独立,不知道对方的实现。例如狗不仅可以叫,还可以动。我们完全可以分别定义Sayer接口和Mover接口,具体代码示例如下

// Sayer 接口
type Sayer interface {Say()
}// Mover 接口
type Mover interface {Move()
}

Dog既可以实现Sayer接口,也可以实现Mover接口

// 实现Sayer接口
func (d Dog) Say() {fmt.Printf("%s会叫汪汪汪\n", d.Name)
}// 实现Mover接口
func (d Dog) Move() {fmt.Printf("%s会动\n", d.Name)
}

同一个类型实现不同的接口互相不影响使用:

var d = Dog{Name: "旺财"}var s Sayer = d
var m Mover = ds.Say()  // 对Sayer类型调用Say方法
m.Move() // 对Mover类型调用Move方法

多种类型实现同一接口

Go语言中不同的类型还可以实现同一接口。例如在我们的代码世界中不仅狗可以动,汽车也可以动。我们可以使用如下代码体现这个关系

// Mover 接口
type Mover interface {Move()
}type Dog struct {Name string
}// 实现Mover接口
func (d Dog) Move() {fmt.Printf("%s会动\n", d.Name)
}// Car 汽车结构体类型
type Car struct {Brand string
}// Move Car类型实现Mover接口
func (c Car) Move() {fmt.Printf("%s速度70迈\n", c.Brand)
}

这样我们在代码中就可以把狗和汽车当成一个会动的类型来处理,不必关注它们具体是什么,只需要调用它们的Move方法就可以了

var obj Moverobj = Dog{Name: "旺财"}
obj.Move() // 旺财会动obj = Car{Brand: "宝马"}
obj.Move()  // 宝马速度70迈

3.空接口

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

package mainimport "fmt"// 空接口作为函数参数
func show(a interface{}) {fmt.Printf("type:%T value:%v\n", a, a)
}func main() {show(521) // type:int value:521show("你好啊")  // type:string value:你好啊
}

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

package mainimport "fmt"func main() {// 空接口作为map值var studentInfo = make(map[string]interface{})studentInfo["name"] = "沙河娜扎"studentInfo["age"] = 18studentInfo["married"] = falsefmt.Println(studentInfo)  // map[age:18 married:false name:沙河娜扎]
}

4.类型断言

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

我们可以借助标准库fmt包的格式化打印获取到接口值的动态类型

var m Moverm = &Dog{Name: "旺财"}
fmt.Printf("%T\n", m) // *main.Dogm = new(Car)
fmt.Printf("%T\n", m) // *main.Car

而想要从接口值中获取到对应的实际值需要使用类型断言,其语法格式如下

x.(T)

其中:

  • x:表示接口类型的变量
  • T:表示断言x可能是的类型

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

var n Mover = &Dog{Name: "旺财"}
v, ok := n.(*Dog)
if ok {fmt.Println("类型断言成功")v.Name = "富贵" // 变量v是*Dog类型
} else {fmt.Println("类型断言失败")
}

如果对一个接口值有多个实际类型需要判断,推荐使用switch语句来实现

// justifyType 对传入的空接口类型变量x进行类型断言
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语言基础之接口

Go语言基础之接口1.Go语言接口类型2.类型与接口的关系一个类型实现多个接口多种类型实现同一接口3.空接口4.类型断言1.Go语言接口类型 每个接口类型由任意个方法签名组成,接口的定义格式如下: type 接口类型名 interface{方法名1( 参数列表1 ) 返回值列…...

【Go自学第一节】GoLang 数据类型

和Java类型,go拥有多种数据类型,可以把它分为四个大类基础类型、聚合类型、引用类型和接口类型 一、基本数据类型 基本数据类型又可以细分为:数字类型(整型、浮点型)、布尔类型、字符串类型 整型 Go 的整型分为有符号…...

学习ForkJoin

学习ForkJoin一、普通解决多线程方式1、案例一2、效果图二、ForkJoin一、普通解决多线程方式 1、案例一 大数据量的List问题处理,多线程分批处理,需要解决的问题: 下标越界。线程安全。数据丢失。 private static ThreadPoolExecutor thre…...

System has not been booted with systemd as init system (PID 1). Can‘t operate.

今天想查看防火墙的状态,但是对防火墙的操作还不熟悉,网上搜到的命令是这样的systemctl status firewalld 结果输入之后出现了这样的错误: System has not been booted with systemd as init system (PID 1). Can’t operate. 然后接着去网上…...

使用Endnote自定义参考文献格式

使用Endnote自定义参考文献格式 使用Endnote插入参考文献,若要设置期刊指定格式或自己想要的参考格式,使用EndNote自定义方法,步骤如下。 注:有的期刊会给出EndNote的格式文件,那样直接导入就行。 文章目录使用Endnot…...

jsPlumb Components Crack

jsPlumb Components Crack 为支持Vue 2,所有组件都添加了包装器。 已为所有组件添加了包装器以支持Svelte。 改进了在流程图生成器中编辑多个选定节点。 jsPlumb组件是一组可嵌入的组件,可将可视连接快速集成到网页中。jsPlumb组件基于jsPlumb Toolkit库…...

Java接口

目录 为什么有接口? 接口的定义和使用 注意 接口的基本使用 接口成员的特点 接口和类之间的关系 为什么有接口? 接口就是一种规则 对行为的抽象 接口侧重于行为 接口的定义和使用 接口用于关键字interface来定义public interface 接口名{ }接口不…...

二叉树OJ题目详解

根据二叉树创建字符串 采用前序遍历的方式,将二叉树转换成一个由括号和数字组成的字符串。 再访问每一个节点时,需要分情况讨论。 如果这个节点的左子树不为空,那么字符串应加上括号和左子树的内容,然后判断右子树是否为空&#x…...

#Vue3篇:响应式工具ref()、toRef()、 toRefs()、reactive()的用法和区别

ref() 定义: ref()接收一个普通的Javascript值作为参数,将其转换为响应式对象(ref对象)。 ref对象有一个.value属性,用于获取和修改之。 参数1: 一个普通的Javascript值作为参数 import { ref } from vue const count ref(0) c…...

docker容器内安装gcc(trunk 最新版本)以及LLVM

1、docker内部只有wget以及git命令 项目需要,得更新docker容器中的gcc和LLVM版本但是由于没有预先安装apt、apt-get以及yum,导致很多安装过程就是鸡生蛋蛋生鸡反应。暂时没有找到合适的解决的方法,如果有大佬知道的话,欢迎留言哈…...

手把手教你如何做数据报表

数据报表是一种数据可视化形式,它将复杂的数据信息通过图形、表格等形式进行展示和解释,让人们更加直观地理解和分析数据。数据报表已成为现代企业决策的必备工具之一。对企业来说,数据报表有很多用处。首先,数据报表可以帮助企业…...

loadrunner的函数lr_paramarr()学习

好久没更新了,还是太懒了,正好最近有用到这个函数,浅浅记录一下 1、首先关联到的参数是个数组,比如用这个函数获取web_reg_save_param(“param”....); 那么保存到的参数是param_1;param_2;param_3;param_4;param_co…...

Hive---数据导出

数据导出 文章目录数据导出Insert 导出将查询的结果导出到本地将查询的结果格式化导出到本地将查询的结果导出到 HDFS 上Hadoop 命令导出到本地Hive Shell 命令导出Export 导出到 HDFS 上sqoop导出Insert 导出 表为student 将查询的结果导出到本地 insert overwrite local d…...

还不会CAD批量打印图纸?学会这招再也不怕

各位工程师,相信大家在工作过程中,经常会遇到需要打印大量图纸文件的时候,那么多的图纸,一张张打印太麻烦,此时便需要用到CAD批量打印功能啦!可是,总有些新手设计师不直达奥CAD批量打印&#xf…...

硬件设计从失败案例中找方法

大家好,我是记得诚。 2022年底,受邀去上海参加电子技术大会,并在一个硬件设计的分论坛做一场演讲,题目是《硬件设计从失败案例中找方法》,一般演讲都是比较紧张的,而且是现场,台下坐着的都是同…...

使用python求PLS-DA的方差贡献率

以鸢尾花数据集为例,实现PLS-DA降维,画出降维后数据的散点图并求其方差贡献率。 效果图 完整代码 # 导入所需库 import numpy as np from sklearn.cross_decomposition import PLSRegression from sklearn.datasets import load_iris from sklearn.pre…...

前端面试题--JavaScript篇

一、JavaScript中的数据类型JavaScript中共有八种数据类型:Number、String、Boolean、Object、Null、Undefined、null、Symbol、BigInt 其中Symbol和BigInt是ES6新增的数据类型Symbol代表独一无二且不可改变的数据类型,主要为了解决可能出现的全局变量冲…...

【批处理脚本】-3.5-pause暂停命令详解

"><--点击返回「批处理BAT从入门到精通」总目录--> 共3页精讲(列举了所有pause的用法,图文并茂,通俗易懂) 在从事“嵌入式软件开发”和“Autosar工具开发软件”过程中,经常会在其集成开发环境IDE(CodeWarrior,S32K DS,Davinci,EB Tresos,ETAS…)中,…...

软件测试11

一 Linux命令的基本格式 格式组成&#xff1a;命令主体 -命令选项 命令参数 常见命令形式&#xff1a; &#xff08;1&#xff09;命令主体 &#xff08;2&#xff09;命令主体 -命令选项 &#xff08;3&#xff09;命令主体 参数 &#xff08;4&#xff09;命令主体 -命令选项…...

2023 面试题js、es6篇

什么是闭包&#xff1f; 闭包的定义 闭包是指能够访问另一个函数作用域中的变量的一个函数。 在js中&#xff0c;只有函数内部的子函数才能访问局部变量&#xff0c; 所以闭包可以理解成 “定义在一个函数内部的函数”。 应用场景 将内部的函数返到外部去&#xff0c;让外部…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...