6. Go接口

news/2025/2/24 19:28:15

一、接口相关概念

理解和掌握接口的使用对于写出优雅且可扩展的 Go 代码至关重要。接口是 Go 语言的核心,它提供了灵活的抽象方式,使得不同类型能够通过共享行为来合作,而不需要彼此依赖具体实现。这种机制对于模块化编程、降低耦合度以及实现多态具有非常重要的作用。

1. 接口是引用类型

Go 中的接口是引用类型,它默认的零值是 nil,表示没有指向任何具体的对象。当一个接口没有被赋值时,它的值为 nil,也就意味着没有实现任何方法。

2. 接口的核心概念:行为的集合

接口是对一组行为的抽象,接口并不定义数据,它只定义了方法签名(声明),即一组未实现的函数。具体的类型通过实现这些方法来实现接口。

  • 接口是行为的集合:接口定义了一些行为规范,任何实现这些方法的类型就能够满足该接口。
  • 实现接口在 Go 中,如果一个类型实现了接口中所有方法,那么这个类型就实现了该接口。

3. Go 的接口实现机制

  • 隐式实现:Go 不需要显式声明类型实现了哪个接口(与 Java 等语言不同)。只要一个类型实现了接口中定义的所有方法,编译器就会自动识别类型实现了该接口。
  • 非侵入式:你不需要在类型定义时明确声明自己实现了某个接口,Go 会在编译时自动检查类型是否符合接口的要求。

4. 接口命名约定

  • 接口名通常以 -er 后缀结尾,用来表示该类型具备某些行为。
    • 例如:ReaderWriterCloser
  • 在包外使用接口时,接口名首字母应大写,以确保符合 Go 的命名规则。

5. 接口设计原则

  • 接口要小:设计接口时,遵循“单一职责原则”,接口不宜过大,应当只包含一个行为的集合。可以通过组合多个小接口来构建复杂接口。
  • 接口命名要简洁明了:接口名应清晰地表达该接口的作用,避免过于笼统或模糊的命名。
  • 接口与结构体结合:接口可以与结构体嵌套使用,通过结构体实现接口定义的行为。接口的设计使得不同类型能够通过实现同一接口,表现出相同的行为。

6. 接口实现的条件

  • 一个类型只有实现了接口中声明的所有方法,它才“实现”了该接口。
  • 如果接口中声明了多个方法,类型必须实现所有这些方法,否则类型就不满足接口。
  • 例外:Go 的接口是“非侵入式”的,即你并不需要在代码中显式声明接口的实现,只要类型具备接口的方法,它就自动实现了接口。

二、实现接口类型实例

1、代码关键点

  1. 结构体定义Person结构体有两个字段 nameage

  2. 方法定义

    • walk()方法是接收者是*Person类型的指针方法(因此可以修改结构体的状态,但没有修改状态)。
    • jump()方法是接收者是p *Person类型的指针,属于一个常见的写法来处理类似结构体的方法。
  3. 接口定义action接口要求实现者有两个方法:walk()jump(),这两个方法分别由Person类型的指针实现。

  4. 接口实现:接口是隐式实现的,即Go不需要显式声明结构体实现了某个接口,只要结构体实现了接口中定义的所有方法,它就自动实现了这个接口。因此,Person类型通过实现walkjump方法,自动实现了action接口。

2、代码示例

package main

import "fmt"

type Person struct {
	name string
	age  int
}

func (*Person) walk() { //Receiver既是实例也是指针类型
	fmt.Println("走")
}
func (p *Person) jump() { //如果添加p,p 是 Person 类型实例的接收者
	fmt.Println("跳")
}

type action interface {
	walk()
	jump()
}

func main() {
	m1 := Person{"xinglujianzhi", 19}
	m2 := &m1 // &m1是指向m1的指针
	m2.walk()
	m2.jump()
	
	//接口部分使用
	var m3 action = m2 // m2是*Person类型,又是action接口类型。Go的赋值中右边的值赋给左边的变量
	m3.walk()          // 通过action接口调用walk 方法
	m3.jump()          //通过action接口调用jump 方法
	//Person结构体类型实现了action中定义的所有方法,所以Person就实现了action的接口,接口类型的实现,与接口概念中的第六条相呼应


}

Go语言的接口实现是隐式的,而不需要显式声明接口实现。

语法糖了解

使用的 m2.walk()m2.jump() 这种方式,本质上是 Go 对指针方法调用的语法糖,它让你不用显式地解引用指针。

var m3 action = m2 也是 Go 中的语法糖,它通过隐式接口实现机制,使得你可以将一个实现了接口的类型赋值给接口类型的变量,而不需要显式地声明接口的实现。


http://www.niftyadmin.cn/n/5864746.html

相关文章

记录一下VScode可以使用nvcc编译,但VS不行的解决方案

最近在学习CUDA编程的东西,出现了一个问题Visual Studio在使用nvcc编译会报错。 D:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\vcruntime.h(197): error: invalid redeclaration of type name "size_t&q…

DeepSeek 助力 Vue 开发:打造丝滑的滑块(Slider)

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…

谷歌浏览器(Google Chrome)扩展程序的安装路径(插件的安装路径)

谷歌浏览器(Google Chrome)扩展程序的安装路径(插件的安装路径),举例:AdBlock 1、点击操作栏:扩展程序--管理扩展程序--我的扩展程序 2、点击“扩展程序”,比如:AdBlock,选择“详情”,找到“ID”…

第8章:LangChain检索增强生成RAG--2.4Advanced RAG【高级RAG】

这一部分详细介绍了 LangChain4j 中的高级 RAG(Advanced RAG)实现。高级 RAG 通过多个模块化组件来增强检索功能,提供了高度的灵活性和定制化能力,一般要做好,多半都会采用此方案 高级 RAG(Advanced RAG) 高级 RAG 可以通过 LangChain4j 实现,涉及以下核心组件: Que…

vue passive 修饰符使用场景

passive的作用 让事件的默认行为立即执行,无需等待事件回调执行完毕 比如滚动事件:默认情况下,浏览器会等待JavaScript事件处理函数(onscroll) 执行完毕后才进行滚动,这可能会导致页面的滚动不够流畅。 使用passive…

自制操作系统前置知识汇编学习

今天要做什么? 为了更好的理解书中内容,需要学习下进制分析和汇编。 汇编语言其实应该叫叫机器指令符号化语言,目前的汇编语言是学习操作系统的基础。 一:触发器 电路触发器的锁存命令默认是断开的,是控制电路触发器…

Hot100 动态规划

动态规划 动规五部曲: 确定dp数组以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组 70. 爬楼梯 - 力扣(LeetCode) 爬到第一层楼梯有一种方法,爬到二层楼梯有两种方法。 那么第一层楼梯再跨两步就到第三…

HttpWatch 9.4.17 Pro网页调试与性能优化 资源工具分享

HttpWatch 9.4.17 Pro 是一款专业的网页调试与网络分析工具,专为开发者和网络管理员设计,帮助您轻松监控、分析和优化网页性能。无论是前端开发、后端调试,还是网络性能优化,HttpWatch 都能为您提供强大的支持。 使用方式&#x…