从零开始学GO ---- 接口

Go语言 -- 接口和指针语法糖 “我不想吹go怎么先进高级,相反就目前为止我觉得它有点莫名其妙” Note:没使用过c语言指针的建议直接找教程看,否则可能越看越糊涂。 指针和语法糖 go语言采用了C语言中指针的概念,简单来说指针就是变量的地址,在C语言中通过[*ptr.]或者[ptr->] 的方式来使用,但是在Go语言中把这两种方式都简化成[ptr.]了,与普通变量一样,看过一篇文章说这是go提供的一个语法糖,示例: fu... 阅读详情

从零开始学GO ---- 接口

接口是一个编程规范,一组方法签名的集合。Go的接口是非侵入式的设置,一个具体类型实现接口不需要在语法上显式地声明,只要具体类型的方法集是接口方法集的超集,就代表该类型实现了接口,编译器在编译时进行方法的校验。接口定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节。

在Go语言中接口(interface)是一种类型,一种抽象的类型。

接口声明

Go语言接口分为 接口字面变量类型和接口命名类型,用interface关键字声明

接口字面变量类型的声明语法:

interface{
	MethodSignature1
	MethodSignature2
}

接口命名类型使用type关键字声明:

type InterfaceName interface{
	MethodSignature1
	MethodSignature2
}

接口定义的大括号内是方法声明的集合,也可以嵌入另一个接口类型匿名字段。

例如:

type Reader interface{
    Read(p []byte) (n int,err error)
}
type Writer interface{
    Writer(p []byte)(n int,err error)
}

type ReadWriter interface{
    Reader
    Writer
}
//《====》等价于
type ReadWriter interface{
    Read(p []byte)(n int,err error)
    Writer(p []byte)(n int,err error)
}

声明新接口类型的特定:

  • 接口的命名一般以"er"结尾
  • 接口定义的内部方法不需要func引导
  • 在接口定义中,只有方法声明没有方法实现
接口初始化

一个对象只要全部实现了接口中的方法,那么就实现了这个接口。换句话说,接口就是一个需要实现的方法列表,因此实现了该接口中所有的方法即实现了接口的初始化。

接口初始化的例子:

// Sayer 接口
type Sayer interface {
	say()
}
//dog和cat接口体
type dog struct {}
type cat struct {}
//因为Sayer接口里只有一个say方法,所以只需要给dog和cat 分别实现say方法就可以实现Sayer接口了。
// dog实现了Sayer接口
func (d dog) say() {
	fmt.Println("汪汪汪")
}

// cat实现了Sayer接口
func (c cat) say() {
	fmt.Println("喵喵喵")
}

func main() {
	var x Sayer // 声明一个Sayer类型的变量x
	a := cat{}  // 实例化一个cat
	b := dog{}  // 实例化一个dog
    //由于cat和dog都实现了Sayer接口,因此Sayer接口变量可以被赋值为cat和dog
	x = a       // 将cat实例直接赋值给x
	x.say()     // 喵喵喵
	x = b       // 将dog实例直接赋值给x
	x.say()     // 汪汪汪
}
接口方法调用

接口方法调用的最终地址是在运行期决定的,将具体类型赋值给接口后,会使用具体类型的方法指针初始化接口变量,当调用接口变量的方法时,节间调用实例的方法。接口方法的调用不是一种直接调用,有一定的运行时开销。

直接调用未初始化的接口变量会产生 panic.

package main

type Printer interface {
	Print()
}

type S struct{}

func (s S) Print() {
	println("print")
}
func main() {
	var i Printer
	//未初始化的接口调用方法会产生panic
	//i.Print()
	//

	i = S{}   //进行初始化
	i.Print() //运行时简介调用S.Print
	//print
}
动态类型和静态类型

动态类型: 接口绑定的具体实例的类型称为接口的动态类型,动态类型随着不同的绑定会发生变化

静态类型: 接口被定义时,其类型就完全被确定,这个类型就是接口的静态类型,静态类型本质特征是接口方法签名集合,两个接口如果方法集合相同的话则静态类型一致可以相互赋值。如果a接口的方法集A,b接口的方法集B,其实B是A的子集合,则a的接口变量可以直接赋值给b的接口变量。

接口运算
接口类型断言

接口断言的语法形式:i.(TypeName) i是接口变量,TypeName可以是接口类型名,也可以是具体类型名

接口查询的两层语义:

  • 如果TypeName是一个具体类型名,则类型断言用来判断接口变量i绑定的实例类型是否就是具体类型TypeName
  • 如果TypeName是一个接口类型名,则类型断言可以判断接口变量i绑定的实例类型是否同时实现了TypeName接口

接口断言的两种语法表现:

直接赋值模式:

o:=i.(TypeName)

  • 如果Typename是具体类型名,并且接口i绑定的实例类型就是具体类型TypeName,则变量o的类型就是TypeName,变量o的值是接口绑定的实例值的副本
  • 如果Typename是接口类型名,如果接口i绑定的实例类型满足接口类型TypeName,则变量o的类型就是TypeName,变量o底层绑定的具体类型实例就是i绑定的实例的副本
  • 否则,程序抛出panic
package main

import "fmt"

//实现一个内部接口
type Inter interface {
	Ping()
	Pang()
}

//实现一个外部接口
type Anter interface {
	Inter //内部接口
	String()
}

type St struct {
	Name string
}

//为 St实现Inter的接口方法集
func (St) Ping() {
	fmt.Println("Ping")
}

func (*St) Pang() {
	fmt.Println("Pang")
}

func main() {
	st := &St{"Tom"}
	var i interface{} = st //定义一个空接口绑定到st

	o := i.(Inter) //判断i绑定的实例是否实现了接口类型Inter
	o.Ping()       //Ping
	o.Ping()       //Pang

	//p := i.(Anter) //判断i绑定的实例是否实现了接口类型Anter
	//p.String()
	//panic: interface conversion: *main.St is not main.Anter: missing method String
	//因为i没有实现String故没有实现Anter,会引发panic

	s := i.(*St) //判断i绑定的实例是否就是具体类型St
	fmt.Printf("%s", s.Name)   //Tom
}

comma, ok 表达式模式:

if o,ok:=i.(TypeName);ok{ }

  • TypeName是具体类型名,接口i绑定的实例类型就是具体类型TypeName,则ok为true,变量o类型就是TypeName,变量o的值就是接口绑定的实例值的副本
  • TypeName是接口类型名,接口i绑定的实例类型满足接口类型TypeName,则ok为true,变量o类型就是接口类型TypeName,变量o底层绑定的具体类型是i绑定的实例的副本
  • 否则,ok为false,变量o是TypeName类型的零值,此种条件下的分支逻辑不应该再去引用o
package main

import "fmt"

//实现一个内部接口
type Inter interface {
	Ping()
	Pang()
}

//实现一个外部接口
type Anter interface {
	Inter //内部接口
	String()
}

type St struct {
	Name string
}

//为 St实现Inter的接口方法集
func (St) Ping() {
	fmt.Println("Ping")
}

func (*St) Pang() {
	fmt.Println("Pang")
}

func main() {
	st := &St{"Tom"}
	var i interface{} = st //定义一个空接口绑定到st

	if o, ok := i.(Inter); ok { //判断i绑定的实例是否实现了接口类型Inter
		o.Ping() //Ping
		o.Pang() //Pang
	}

	if p, ok := i.(Anter); ok {
		//由于i没有实现接口Anter,故ok为false,程序不执行到这里
		p.String()
	}

	if s, ok := i.(*St); ok {
		fmt.Printf("%s", s.Name) //Tom
	}

}

接口类型查询

接口类型查询语法:

switch v:=i.(type){
case type1:
	xxxx
case type2:
    xxxx
default:
    xxxx
}
  • i是一个接口类型
  • case后可以接接口类型名,也可以接 非接口类型名
    • case 接口类型名,如果i绑定的实例类型实现了该接口类型的方法则匹配成功,v的类型是接口类型,v底层绑定的实例是i绑定具体类型实例的副本
    • case 具体类型名,如果接口变量i绑定的实例类型和该具体类型相同,则匹配成功,此时v就是该具体类型变量,v的值是i绑定的实例值的副本
    • 均不匹配的话执行default,v的值为0,没有意义
python使用TensorRT报错,多线程或多进程中使用问题 python使用TensorRT报错,Cuda Runtime问题 阅读详情

相关推荐

Bellhop水声信道模型的仿真

Bellhop是一种基于射线追踪的水声信道模型,广泛用于预测水下环境中的声压场。它通过模拟声波在水中的传播路径,计算声场分布,适用于复杂的水下通信场景。

yt94832的博客 1315

GoLang学习笔记之基础语法(三):指针与Map

本章将介绍go语言中指针的理解与使用,同时介绍go语言中的又一个引用数据类型map。

qq_41736299的博客 1825

吃透 AM32 无人机电调:从源码架构到工作原理的全方位解析(附实践指南)(中)

介绍了三相电机控制中的SVPWM算法实现及保护机制设计。SVPWM部分详细解析了电压矢量扇区判断、占空比计算和过调制保护,通过限制占空比范围(0-100%)防止电机失控,并提供了完整的代码实现。保护模块则重点分析了过流、过压/欠压、过温三种保护机制,采用分级处理策略(硬保护停机/软保护降功率)确保系统安全。此外,文章还介绍了参数管理模块在STM32 Flash中的存储方案,包括参数定义、数据结构和读写操作,为电机控制系统提供了完整的解决方案。

bother3000的博客 1389

Go语言 - 接口

接口类型 在Go语言中接口(interface)是一种类型,一种抽象的类型。 interface是一组method的集合,是duck-type programming的一种体现。接口做的事情就像是定义一个协议(规则) 举例:只要一台机器有洗衣服和甩干的功能,我就称它为洗衣机。不关心属性(数据),只关心行为(方法) 为了保护你的Go语言职业生涯,请牢记接口(interface)是一种类...

Waller_的博客 293

032、准谐振反激变换器(QR-Flyback)原理

文章摘要: 本文以65W PD快充炸管案例切入,解析准谐振反激变换器(QR-Flyback)原理。通过主动利用漏感与MOS结电容的谐振,在Vds波谷开通实现近似ZVS,显著降低开关损耗与电压应力。对比传统反激,QR模式轻载效率提升8%,Vds尖峰减少23%。关键设计要点包括:变压器漏感需<3%、谷底检测电路需抗干扰、启动阶段需防过冲。推荐NCP1340等专用控制芯片,并强调VCC电容优选低ESR陶瓷材质。QR适用于30W-150W场景,其核心优势在于轻载效率优化,但需平衡漏感控制与可靠性。作者结合实测数据与

Jack010169的博客 116

【git】git: ‘interpret-trailers’ is not a git command. See ‘git --help’

cents 7.6系统. yum源安装git最新版本是1.8.3 报错: git: 'interpret-trailers' is not a git command. See 'git --help'. cannot insert change-id line in .git/COMMIT_EDITMSG 解决: git add xxx git commit -m "xxx" 然后修改 vim .git/hooks/commit-msg #if test -n "${reviewurl}" ; th

machh的专栏 4758

go语言学习:面向对象(匿名字段)

一、匿名字段 go支持只提供类型而不写字段名的方式,也就是匿名字段,也称为嵌入字段 package main import "fmt" // go支持只提供类型而不写字段名的方式,也就是匿名字段,也称为嵌入字段 //人 type Person struct { name string sex string age int } type Studen...

Mr_qing的博客 599

【教程4>第10章>第13节】基于FPGA的图像双边滤波开发——单通道双边滤波Verilog实现

本文介绍了基于Vivado 2022.2的单通道高斯滤波FPGA实现方案。主要内容包括:1)采用3×3窗口像素提取、高斯权值计算、exp指数运算等模块构建双边滤波系统;2)详细分析了Verilog HDL实现的顶层设计文件,包含窗口数据生成、指数计算、混合权重、归一化处理等关键模块;3)展示了图像双边滤波器的RTL结构图。该设计为后续实现RGB三通道图像高斯滤波及MATLAB联合仿真奠定了基础。

FPGA/MATLAB学习教程/源码/项目合作开发 262

Go语言基础之接口

目录 一、接口 二、接口类型 三、为什么要使用接口 四、接口的定义 五、实现接口的条件 六、接口类型变量 七、值接收者和指针接收者实现接口的区别 7.1 值接收者实现接口 7.2 指针接收者实现接口 ...

weixin_30470643的博客 374

PCL 利用RANSAC改进的ICP算法

本文介绍了一种基于RANSAC改进的ICP点云配准算法。算法原理部分阐述了在ICP迭代过程中使用RANSAC剔除错误匹配点对的方法。

点云侠的博客 196

IPOP 使用详解 (附IPOP工具包)

IP 地址动态绑定功能;路由信息查询和配置功能;MAC 地址信息查询和修改功能;MAC 、主机信息扫描功能;本机网络报文统计功能;本机端口列表、远程端口扫描功能;端口映射功能;网卡流量统计功能;本机 IP 报文捕获和发送功能;终端控制功能(支持 telnet 、 dos、 ssh、 sftp 、ftp、com 等协议);TCL 脚本支持;多种服务功能( tcp/udp/ping/telnet/ftp/tftp/web/team/syslog/smtp );

悦分享 1万+

从零开始学Go之接口(一):接口

接口是双方约定的一种合作协议。接口实现者不需要关心接口会被怎样使用,调用者也不需要关心接口的实现细节。 接口是一种类型,也是一种抽象结构,不会暴露所含数据的格式、类型及结构。 声明: 接口类型是由一组方法签名定义的集合 type 接口类型名 interface{ 方法名1( 参数列表1 ) 返回值列表1 方法名2( 参数列表2 ) 返回值列表2 … } typ...

226

基于工作流的低代码AI应用开发:Flock平台核心架构与实战指南

在AI应用开发领域,工作流编排正成为连接大语言模型(LLM)能力与复杂业务逻辑的关键技术。其核心原理是将任务分解为模块化节点,通过可视化方式定义执行顺序与数据流向,从而实现灵活可控的自动化流程。这种范式极大地提升了开发效率,降低了技术门槛,使得开发者能够聚焦于业务设计而非底层代码。在技术价值层面,工作流编排支持检索增强生成(RAG)、多智能体协作等高级模式,并能通过人工干预节点确保关键流程的可靠性与合规性。其典型应用场景包括智能客服、自动化办公、数据分析助手等。本文以Flock平台为例,深入解析了如何利用其

weixin_26848497的博客 381

从零开始学Go之接口(三):常用内置接口

Stringers: fmt包中定义的Stringer是最普遍的接口之一。 type Stringer interface { String() string } Stringer是一个可以用字符串描述自己的类型。fmt包(还有很多包)都通过此接口来打印值。 type Person struct { Name string Age int } ​...

467

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

从零开始学Go之接口(二):类型断言与类型选择

类型断言: 类型断言提供了访问接口值底层具体值的方式。 变量名 := 接口名.(判断类型名) var i interface{} = "hello" s := i.(string) //f := i.(float64) //编译错误,因为i的值不为float64 当只有一个返回值时,返回值为对应类型的值,而判断类型名与接口值类型不对应时,程序会宕机panic 此时...

240

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【Golang从零开始的修炼之路】Go接口的那些事~

Go 接口是一种类型,它定义了一组方法签名。接口类型的变量可以存储任何实现了该接口的具体类型的值,实现接口需要通过实现接口签名中的所有方法来完成。

技术知识分享 327

Go语言入门指南:从零开始学Go

/ 基本函数// 多个参数类型相同,可以简写// 多返回值return 0, errors.New("除数不能为零")// 命名返回值return // naked return,自动返回命名返回值// 可变参数total := 0// 使用Go语言以其简洁、高效和强大的并发支持,成为现代后端开发的重要选择。环境搭建和第一个程序基础语法(变量、常量、数据类型、运算符)控制流程(条件、循环、switch)函数和方法数组、切片和Map结构体和接口错误处理。

好代码自己会说话,烂代码才需要注释来圆谎 4744

探索Go语言的无限可能:《从零开始学Go》

探索Go语言的无限可能:《从零开始学Go》 golang-bookA book on Go, contains fundamentals but also recipes项目地址:https://gitcode.com/gh_mirrors/gol/golang-book 在编程世界里,Go语言以其简洁、高效和并发性能优秀的特点,迅速成为开发者们的宠儿。为了帮助更多的初学者轻松入门Go语言,我们...

gitblog_00031的博客 466

从零开始学Golang:AI赋能下的高效编程之旅

开发AI智能应用,就下载InsCode AI IDE,一键接入DeepSeek-R1满血版大模型! 标题:从零开始学Golang:AI赋能下的高效编程之旅 引言 在当今快速发展的科技时代,编程语言的多样性和复杂性对开发者提出了更高的要求。而Golang(Go语言)作为近年来备受推崇的一种编程语言,因其简洁、高效和强大的并发处理能力,逐渐成为许多开发者的首选工具。然而,对于初学者而言,掌握Golan...

SnowflakeJaguar14的博客 1008

从零开始构建gRPC的Go服务

第一步首先定义gRPC服务以及方法请求和响应类型。然后在服务定义中定义RPC方法,指定它们的请求和响应类型。一个简单的RPC,其中客户端使用存根向服务端发送请求并等待响应返回,就像正常的函数调用一样。服务端流式RPC,客户端向服务端发送请求并获取流以读回一系列消息。客户端从返回的流中读取,直到没有更多消息为止。客户端流式RPC,其中客户端写入一系列消息并将它们发送到服务端,再次使用提供的流。一旦客户端完成了消息的写入,它会等待服务端读取所有消息并返回其响应。

ldxxxxll的博客 1478

【从零开始学习Go】Go 语言接口和泛型(十一)

本文摘要: 本文系统介绍了Go语言中接口和泛型两大特性。接口部分阐述了其定义语法、隐式实现机制、动态类型特性、指针接收者区别、空接口用法及多态实现,并与C++进行了对比分析。泛型部分从基本语法入手,讲解了类型参数、约束概念及其在函数和自定义容器中的应用,解决了代码复用与类型安全的问题。全文通过丰富代码示例,清晰展示了Go接口和泛型的设计思想、实现方式和实际应用场景。

XIOUR的博客 741

Golang Microservices Go:从零开始构建生产级微服务架构的完整指南

Golang Microservices Go 是一个基于 Go 语言的微服务架构模板项目,它集成了 PSQL 数据库、Docker 容器化和 Cucumber 测试框架,采用 REST API 设计风格,并结合了 Gin Go 框架和 GORM ORM 工具,实现了分页功能和清晰的 Clean Architecture 设计模式。本文将带你从零基础开始,全面了解如何使用这个强大的模板构建生产级别

gitblog_00415的博客 948

Go-Ethereum完全指南:从零开始掌握以太坊官方Golang实现

Go-Ethereum(简称Geth)是以太坊协议的官方Golang实现,作为以太坊网络的核心客户端之一,它允许用户参与以太坊区块链网络、创建智能合约、进行代币转账等操作。本指南将帮助新手快速入门Geth,从安装到基础使用,全面掌握这个强大工具的核心功能。 ## 为什么选择Go-Ethereum? Go-Ethereum是以太坊生态系统中最受欢迎的客户端之一,由以太坊基金会主导开发。它具有以下

gitblog_00190的博客 976

Golang入门完全指南:为什么它是云原生时代最值得学的语言?(Backend-NodeJS-Golang-Interview_QA)

想系统入门 Go 语言却不知道从哪下手?这份 **Golang 入门完全指南** 就是为你准备的。在云原生、微服务与后端开发岗位需求持续攀升的今天,Go(Golang)凭借简洁的语法、原生的并发模型和强悍的执行性能,成为越来越多开发者转型与进阶的首选语言。本文不仅会带你梳理 Go 语言入门路线与核心概念,还会结合开源仓库 **Backend-NodeJS-Golang-Interview_QA**

gitblog_00120的博客 890

Mockery完全教程:从零开始掌握Go接口Mock生成终极指南

Mockery是Go语言生态中一款强大的接口Mock代码自动生成工具,它能帮助开发者轻松创建符合测试需求的模拟实现,显著提升单元测试的编写效率。无论是新手还是有经验的Go开发者,掌握Mockery都将为你的测试工作带来革命性的改变。 ## 🚀 为什么选择Mockery? 在Go语言开发中,接口是实现依赖注入和测试隔离的核心机制。Mockery作为一款专注于Go接口的Mock生成工具,具有以下

gitblog_00093的博客 785
上一篇: 从零开始学GO ---- 错误处理
下一篇: Golang通过反射对结构体进行赋值和其他操作
coding丁
博客等级 码龄9年 383粉丝 147原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值