《快学 Go 语言》第 9 课 —— 接口

【Golang】Go语言中type关键字到底是什么? 在Go语言中,`type`关键字是构建自定义数据类型和声明新类型的基础。通过`type`,我们可以定义类型别名、结构体、接口、函数类型等多种数据类型,这些自定义类型极大地增强了Go语言的灵活性和表达能力。本文将结合实际案例,详细探讨`type`在Go语言中的多种用法。 阅读详情

640?wx_fmt=png

接口是一个对象的对外能力的展现,我们使用一个对象时,往往不需要知道一个对象的内部复杂实现,通过它暴露出来的接口,就知道了这个对象具备哪些能力以及如何使用这个能力。

我们常说「佛有千面」,不同的人看到的佛并不一样。一个复杂的复合对象常常也可以是一个多面手,它具备多种能力,在形式上实现了多种接口。「弱水三千,只取一瓢」,使用时我们根据不同的场合来挑选满足需要的接口能力来使用这个对象即可。

Go 语言的接口类型非常特别,它的作用和 Java 语言的接口一样,但是在形式上有很大的差别。Java 语言需要在类的定义上显式实现了某些接口,才可以说这个类具备了接口定义的能力。但是 Go 语言的接口是隐式的,只要结构体上定义的方法在形式上(名称、参数和返回值)和接口定义的一样,那么这个结构体就自动实现了这个接口,我们就可以使用这个接口变量来指向这个结构体对象。下面我们看个例子

package main

import "fmt"

// 可以闻
type Smellable interface {
  smell()
}

// 可以吃
type Eatable interface {
  eat()
}

// 苹果既可能闻又能吃
type Apple struct {}

func (a Apple) smell() {
  fmt.Println("apple can smell")
}

func (a Apple) eat() {
  fmt.Println("apple can eat")
}

// 花只可以闻
type Flower struct {}

func (f Flower) smell() {
  fmt.Println("flower can smell")
}

func main() {
  var s1 Smellable
  var s2 Eatable
  var apple = Apple{}
  var flower = Flower{}
  s1 = apple
  s1.smell()
  s1 = flower
  s1.smell()
  s2 = apple
  s2.eat()
}

--------------------
apple can smell
flower can smell
apple can eat

空接口

如果一个接口里面没有定义任何方法,那么它就是空接口,任意结构体都隐式地实现了空接口。

Go 语言为了避免用户重复定义很多空接口,它自己内置了一个,这个空接口的名字特别奇怪,叫 interface{} ,初学者会非常不习惯。之所以这个类型名带上了大括号,那是在告诉用户括号里什么也没有。我始终认为这种名字很古怪,它让代码看起来有点丑陋。

空接口里面没有方法,所以它也不具有任何能力,其作用相当于 Java 的 Object 类型,可以容纳任意对象,它是一个万能容器。比如一个字典的 key 是字符串,但是希望 value 可以容纳任意类型的对象,类似于 Java 语言的 Map 类型,这时候就可以使用空接口类型 interface{}。

package main

import "fmt"

func main() {
 // 连续两个大括号,是不是看起来很别扭
    var user = map[string]interface{}{
        "age": 30,
        "address": "Beijing Tongzhou",
        "married": true,
    }
    fmt.Println(user)
    // 类型转换语法来了
 var age = user["age"].(int)
    var address = user["address"].(string)
    var married = user["married"].(bool)
    fmt.Println(age, address, married)
}

-------------
map[age:30 address:Beijing Tongzhou married:true]
30 Beijing Tongzhou true

接口变量的本质

在使用接口时,我们要将接口看成一个特殊的容器,这个容器只能容纳一个对象,只有实现了这个接口类型的对象才可以放进去。

640?wx_fmt=png
图片

接口变量作为变量来说它也是需要占据内存空间的,通过翻阅 Go 语言的源码可以发现,接口变量也是由结构体来定义的,这个结构体包含两个指针字段,一个字段指向被容纳的对象内存,另一个字段指向一个特殊的结构体 itab,这个特殊的结构体包含了接口的类型信息和被容纳对象的数据类型信息。

// interface structure
type iface struct {
  tab *itab  // 类型指针
  data unsafe.Pointer  // 数据指针
}

type itab struct {
  inter *interfacetype // 接口类型信息
  _type *_type // 数据类型信息
  ...
}

package main

import "fmt"
import "unsafe"

func main() {
    var s interface{}
    fmt.Println(unsafe.Sizeof(s))
    var arr = [10]int {1,2,3,4,5,6,7,8,9,10}
    fmt.Println(unsafe.Sizeof(arr))
    s = arr
    fmt.Println(unsafe.Sizeof(s))
}

----------
16
80
16

用接口来模拟多态

前面我们说到,接口是一种特殊的容器,它可以容纳多种不同的对象,只要这些对象都同样实现了接口定义的方法。如果我们将容纳的对象替换成另一个对象,那不就可以完成上一节我们没有完成的多态功能了么?好,顺着这个思路,下面我们就来模拟一下多态

package main

import "fmt"

type Fruitable interface {
    eat()
}

type Fruit struct {
    Name string  // 属性变量
    Fruitable  // 匿名内嵌接口变量
}

func (f Fruit) want() {
    fmt.Printf("I like ")
    f.eat() // 外结构体会自动继承匿名内嵌变量的方法
}

type Apple struct {}

func (a Apple) eat() {
    fmt.Println("eating apple")
}

type Banana struct {}

func (b Banana) eat() {
    fmt.Println("eating banana")
}

func main() {
    var f1 = Fruit{"Apple", Apple{}}
    var f2 = Fruit{"Banana", Banana{}}
    f1.want()
    f2.want()
}

---------
I like eating apple
I like eating banana

接口的组合继承

接口的定义也支持组合继承,比如我们可以将两个接口定义合并为一个接口如下

type Smellable interface {
  smell()
}

type Eatable interface {
  eat()
}

type Fruitable interface {
  Smellable
  Eatable
}

type Fruitable interface {
  smell()
  eat()
}

接口变量的赋值

变量赋值本质上是一次内存浅拷贝,切片的赋值是拷贝了切片头,字符串的赋值是拷贝了字符串的头部,而数组的赋值呢是直接拷贝整个数组。接口变量的赋值会不会不一样呢?接下来我们做一个实验

package main

import "fmt"

type Rect struct {
    Width int
    Height int
}

func main() {
    var a interface {}
    var r = Rect{50, 50}
    a = r

    var rx = a.(Rect)
    r.Width = 100
    r.Height = 100
    fmt.Println(rx)
}

------
{50 50}

指向指针的接口变量

如果将上面的例子改成指针,将接口变量指向结构体指针,那结果就不一样了

package main

import "fmt"

type Rect struct {
    Width int
    Height int
}

func main() {
    var a interface {}
    var r = Rect{50, 50}
    a = &r // 指向了结构体指针

    var rx = a.(*Rect) // 转换成指针类型
    r.Width = 100
    r.Height = 100
    fmt.Println(rx)
}

-------
{100 100}

下一节我们开讲 Go 语言的错误处理

640?wx_fmt=png

扫一扫上面的二维码关注「码洞」,免费阅读《快学 Go 语言》更多章节

全新YOLO26有效涨点改进专栏目录 | 本专栏持续更新500+篇内容 | 包含各种卷积、主干网络、各种注意力机制、检测头、损失函数、小目标检测改进、二次创新模块、独家创新等几百种创新点改进 🔥《2026年YOLO26改进专栏》🔥 🚀持续更新500+最前沿创新改进点(顶会顶刊论文/独家创新策略),涵盖主干网络、各种卷积、注意力机制、检测头等模块,助力科研论文发表与模型性能提升,支持检测/分割/分类任务。订阅即获完整可运行项目,提供专业QQ答疑群,适合科研发论文(SCI/CCF/核心)及工业应用(PCB/医学/遥感检测)。专栏价格将逐步上涨,早订更优惠! ⭐特色:非计算机专业友好、模块可自由组合、全网独家创新;📌适用:研究生大论文和小论文创新、小目标检测、多领域科研应用,满足不同研究需求。 阅读详情

相关推荐

VLA强化学习训练:π0到π0.5的技术优化与实现

视觉语言动作模型(VLA)作为多模态强化学习的重要分支,通过融合视觉、语言和环境状态数据实现智能决策。其核心技术在于多模态特征融合与动作空间设计,其中PPO算法因其出色的训练稳定性成为首选方案。在工程实践中,延迟补偿机制和课程学习设计能显著提升模型性能,如在四足机器人项目中使避障成功率提升47%。针对实际部署中的性能下降问题,需要特别关注硬件量化参数和控制频率一致性等关键因素。本文通过π0与π0.5版本的对比实验,详细解析了VLA模型在机械臂控制等具身智能场景中的优化路径。

weixin_29041767的博客 248

接口的变量(引用变量)

例: List<?> list=new ArrayList<?> Map&amp

zjpp2580369的博客 5771

数电实训:万年历

万年历

Lmyccq的博客 1万+

【Golang】三分钟让你快速了解Go语言&为什么我们需要Go语言?

Go编译速度快的几个原因使用import引用管理方式没有模板编译负担1.5版本后编译器的优化语言本身关键字很少。

Yaoyao2024的博客 3690

IAR调试CC1310的错误:Fatal error:Failed to connect to the XDS emlulator (Error -241 @ 0x0:)

从simplelink_cc13x0_sdk_2_10_00_36导入collector工程后,rebuild后进行debug,出现了如图错误:Fatal error:Failed to connect to the XDS emlulator (connect ICEPick)...(Error -241 @ 0x0)A router subpath could not be accessed....

qq_40417648的博客 6228

【为K8s的coredns配置上游DNS服务器】

为K8s的coredns配置上游DNS服务器一、背景描述二、如何修改coredns达到目的三、修改coredns 解析指定域名走指定dns①、get coredns configmap②、修改coredns configmap③、查询现有coredns pod并逐个重启④、验证解析是否正确 一、背景描述 有一个项目需要部署到客户内网,并通过nat映射实现外网访问! 项目中有多个服务之间调用是走的外网域名,项目采用k8s集群容器部署,客户的网络情况导致服务之间通过外网域名互调时总是 connection ti

那个那个 6673

GO开篇:手握Java走进Golang的世界

Go简介、Go和Java的对比

健身变秃,coding变强 1万+

ChatGPT设置密钥后Codex免手机验证:配置顺序与身份凭证复用机制

API Key 是一种用于身份识别的凭证,其核心原理是通过预配置的密钥替代交互式登录流程。在开发工具中,密钥认证优先级通常高于会话认证,当本地存在有效密钥时,工具会直接复用该凭证,从而减少重复验证环节。这种机制的技术价值在于提升开发效率与配置一致性,尤其适用于多设备切换、CI/CD 流水线及编程辅助工具等场景。以 Codex 为例,在 ChatGPT 界面提前配置 API 密钥后,Codex 启动时可读取持久化存储的密钥,避免触发手机号验证,实现身份凭证的跨入口复用。

weixin_33940469的博客 493

十分钟带你入门Go语言(Golang)开发

本文首先介绍了以下Go语言的由来以及基本特点与应用,我们也知道它是一门很有生命力的编程语言,才发展10多年就已经在TIOBE排名第八,而且还正在往上发展。接着介绍了Go语言的开发环境的搭建,讲解了Go Module和Go Package的作用和使用,最后从零搭建并运行了一个Hello World程序,这个Hello World项目虽小,但是已经包含了Go项目大部分的知识点了,大项目都是在这个基础上发展而来的。最后介绍了Go很强的一个功能:`交叉编译`,只需一台主机,就可以开发适合于多个平台下的程序,说明Go

Go与Python双剑合一 2万+

uniapp - 获取设备麦克风权限+麦克风设备列表,用户可选择切换麦克风设备功能,选择麦克风采集设备后点击录制音频外部声音+可随时暂停/继续录音+记录音频录制时长(支持在线播放试听或下载MP3文件)

uniapp获取麦克风设备列表,uniapp录制声音,Uniapp获取麦克风权限,uniapp苹果ios安卓app获取麦克风设备列表,Uniapp H5获取浏览器麦克风并实现录音,Uniapp实现麦克风权限管理与音频录制全流程,uni-app实战案例:实现H5页面麦克风权限获取与录音功能,uni-app音频录制,uniapp麦克风授权窗口,uniapp获取iOS麦克风权限,实现前端录音并播放,把音频传给后端接口处理,获取麦克风并实现录音功能,前端获取/切换麦克风播放采集音频和采集音量大小,前端调用麦克风实现

🏆 前端领域优质创作者 2984

【27】软考软件设计师——数据流图(DFD)补全题满分精讲|下午15分大题深度拆解

本文是《软件设计师·50讲通关|从零基础到工程师职称》专栏第27篇,深度精讲**下午案例题第1道必考大题:数据流图(DFD)补全**,该题单题分值高达**12 ~ 15分**,是整张试卷最稳的保底得分大题。我结合多年备考复盘与真题阅卷规则,超详细拆解DFD四大核心元素标准定义、机考绘图规范、三层分层逻辑、**父图子图平衡刚性扣分规则**,升级强化版「DFD满分补全三步法」;复刻历年高频真题完整流程,拆解缺失数据流定位、实体/存储辨析、平衡改错、文字需求对照全流程,配套**阅卷满分答题话术、机考避坑细则

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 593

Go 语言接口

在上面的例子中,我们定义了一个接口Phone,接口里面有一个方法call()。然后我们在main函数里面定义了一个Phone类型变量,并分别为之赋值为NokiaPhone和IPhone。Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。/* 实现接口方法 *//* 定义结构体 *//* 定义接口 *//* 方法实现 */

虎头金猫:授渔优于赠鱼,兴趣引领智慧,探索之乐尤显珍贵。商务合作+:Libin9iOak ,万粉变现+:优快云WF,虎哥承诺每年免费为100名C站创作者做账号流量诊断服务! 2174

【AirPlay】苹果认证MFI学习

配件认证是一个过程,通过这个过程,可验证其配件符合MFi技术规范,并通过苹果指定的任何认证测试。MFi门户中的产品计划 "认证 "页面将指导你完成特定配件所需的认证步骤,并指出何时完成所有要求。在完成所有MFi认证要求之前,你不得制造、分发或销售任何配件。在开始MFi认证过程之前,你必须测试你的配件,以确保它符合最新的MFi技术规范,通过产品计划 "测试计划 "上的所有适用测试,并与它将声称具有兼容性的每个苹果设备兼容。

天天的博客 2277

【Go语言入门教程】Go语言简介

文章目录Go语言简介Go语言创始人1) Ken Thompson2) Rob Pike3) Robert GriesemerGo 是编译型语言为什么要学习Go语言Go语言吉祥物Go语言的特性有哪些?语法简单并发模型内存分配垃圾回收静态链接标准库工具链Go语言为并发而生哪些项目使用Go语言开发?1) [Docker](http://c.biancheng.net/docker/)2) Go语言3) Kubernetes4) etcd5) beego6) martini7) codis8) delve哪些大公司

qq_41854911的博客 2万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

【Golang】go编程语言适合哪些项目开发?

Go编程语言凭借其简洁、高效和可靠的特性,适用于各种项目开发。无论是网络编程、大数据处理、云计算、Web开发还是嵌入式系统,Go语言都能够提供出色的性能和可扩展性。希望本文能够帮助读者了解Go语言的优势,并在项目开发中做出明智的选择。😊🙏如果大家对相关文章感兴趣,可以关注公众号"架构殿堂",会持续更新AIGC,java基础面试题, netty, spring boot, spring cloud等系列文章,一系列干货随时送达!

Venus's Blog 2万+

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

GO语言中的接口(interface)

在Go语言中,接口(interface)是方法的集合,它允许我们定义一组方法但不实现它们,任何类型只要实现了这些方法,就被认为是实现了该接口。接口更重要的作用在于多态实现,它允许程序以多态的方式处理不同类型的值。接口体现了程序设计的多态和高内聚、低耦合的思想。

lp15929801907的博客 4321

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

想系统学习GO语言(Golang),能推荐几本靠谱的书吗?

以下内容来自知乎: 学习任何一门语言,都要学习好基础,把基础打牢,那些框架对你来说都是工具,你自己的基础好,懂得了他们的原理,自己就可以创造更优秀的框架。 基础推荐官方文档,没有什么比这个更清晰了。官方文档可以看这个中文的,比较快一些 https://go-zh.org/doc/ 其次参考这个Go指南,练习一遍 https://tour.go-zh.org/welcome/1 现在对Go语言应该有了一个全面的认识,然后你再结合Go语言圣经这本书,深入理解Go的基础。 Go语言圣经中文版 https

Mick_^_^的博客 8342

[Go语言入门] 13 Go语言接口(interface)详解

Go语言入门, Go语言接口

时空旅客的专栏 7826

Go by Example / Golang入门教程(非常详细)

转载:https://gobyexample.com/ Go by Example Gois an open source programming language designed for building simple, fast, and reliable software. Go by Exampleis a hands-on introduction to Go u...

Flyer的后花园 2803

为什么我们要学go语言?go语言的优势

但是 Go 语言更是对 C 语言最彻底的一次扬弃,它舍弃了 C 语言中灵活但是危险的指针运算,还重新设计了 C 语言中部分不太合理运算符的优先级,并在很多细微的地方都做了必要的打磨和改变。下划线_是一个特殊的标识符,称为空白标识符,它可以像其他标识符那样用于变量的声明或赋值(任何类型都可以赋值给它),但任何赋给这个标识符的值都将被抛弃,因此这些值不能在后续的代码中使用,也不可以使用_作为变量对其它变量进行赋值或运算。切片是可以动态双倍扩容的,使用的是数组内置的添加,复制功能。列表的底层数据结构是双向链表。

weixin_56242987的博客 940

“Go语言第一课”结课了

就在家家户户刚刚过完虎年元宵佳节之际,我的Go语言专栏:《Tony Bai·Go语言第一课》[1]也迎来了它的最后一讲结术语[2]。这门专栏的撰写开始于2021年5月中旬,翻看我用于管理专...

TonyBai 5493

Go语言接口为什么是颠覆性的?

什么是接口(Interface) 其实说白了,接口就是一种协议,统一一个标准。你要调用我,那你就必须实现我的这些方法。我不需要知道你是怎么实现的,但是你一定要实现。甚至在Objec-C当中都不叫interface,直接protocol。 我相信不少刚接触interface的人会跟我有一样的疑惑,我实现接口跟不实现接口没什么区别啊?反正都要实现这些方法。问题的误区就在于,接口的使用并不是单人开发...

苏南生的优快云博客 2285
上一篇: 作为程序员,你是如何在工作以后找到女朋友的?
下一篇: 《快学 Go 语言》第 10 课 —— 错误与异常
codehole_
博客等级 码龄7年 34粉丝 132原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值