9.1 Go Interface 基础知识学习笔记
2026/9/4 8:06:49 网站建设 项目流程

9.1 Go Interface 基础知识学习笔记

1. 接口的定义

接口是一组方法签名的集合,定义了"行为"但不实现:

typeShapeinterface{Area()float64}typeWriterinterface{Write([]byte)(int,error)}

要点

  • 接口只声明方法签名,没有实现代码
  • 任何类型只要实现了接口的所有方法,就自动满足该接口,不需要显式声明
  • 这叫做隐式实现(duck typing),Go 不像 Java 需要implements关键字

2. 实现接口

Rectangle 和 Circle 都实现了Area() float64方法,因此它们都自动满足Shape接口:

typeRectanglestruct{Widthfloat64Heightfloat64}func(r Rectangle)Area()float64{returnr.Width*r.Height}typeCirclestruct{Radiusfloat64}func(c Circle)Area()float64{returnmath.Pi*c.Radius*c.Radius}

同样,Writer 接口定义如下:

typeWriterinterface{Write([]byte)(int,error)}

FileWriter 和 ConsoleWriter 都实现了Write([]byte) (int, error)方法,自动满足Writer接口:

typeFileWriterstruct{Filenamestring}func(fw FileWriter)Write(data[]byte)(int,error){fmt.Printf("Writing %d bytes to file: %s\n",len(data),fw.Filename)fmt.Printf("Content: %s\n",string(data))returnlen(data),nil}typeConsoleWriterstruct{}func(cw ConsoleWriter)Write(data[]byte)(int,error){fmt.Printf("Console: %s",string(data))returnlen(data),nil}

要点:没有implementsextends等关键字。只要方法签名完全匹配(方法名、参数类型、返回值类型),就自动实现接口。


3. 接口作为函数参数 — 多态

函数接收接口类型参数时,可以传入任何实现了该接口的类型:

funcprintShapeInfo(s Shape){fmt.Printf("Shape area: %.2f\n",s.Area())}funcwriteMessage(w Writer,messagestring){w.Write([]byte(message))}

不同类型传入同一个函数,表现出不同行为(多态):

rect:=Rectangle{Width:5,Height:3}circle:=Circle{Radius:4}printShapeInfo(rect)// 输出: Shape area: 15.00printShapeInfo(circle)// 输出: Shape area: 50.27fileWriter:=FileWriter{Filename:"output.txt"}consoleWriter:=ConsoleWriter{}writeMessage(fileWriter,"Hello, File!")// 输出: Writing 12 bytes to file: output.txt// Content: Hello, File!writeMessage(consoleWriter,"Hello, Console!")// 输出: Console: Hello, Console!

要点:函数不在乎传入的具体类型,只在乎它是否实现了接口要求的方法。这就是多态——同一接口,不同实现,不同行为。


4. 接口切片 — 存储不同类型

接口类型的切片可以存储所有实现了该接口的不同类型:

shapes:=[]Shape{rect,circle}vartotalAreafloat64for_,shape:=rangeshapes{totalArea+=shape.Area()}fmt.Printf("Total area of all shapes: %.2f\n",totalArea)// 输出: Total area of all shapes: 65.27writers:=[]Writer{fileWriter,consoleWriter}fori,writer:=rangewriters{message:=fmt.Sprintf("Message %d from writer\n",i+1)writeMessage(writer,message)}// 输出: Writing 22 bytes to file: output.txt / Content: Message 1 from writer// Console: Message 2 from writer

要点[]Shape可以同时存放 Rectangle 和 Circle,[]Writer可以同时存放 FileWriter 和 ConsoleWriter。这在没有接口的语言中是无法实现的(数组/切片要求所有元素类型相同)。


5. 接口赋值

接口变量可以动态切换底层类型:

varshape Shape shape=rect// Rectangle 实现了 Shapefmt.Printf("Shape (Rectangle) area: %.2f\n",shape.Area())// 15.00shape=circle// Circle 也实现了 Shapefmt.Printf("Shape (Circle) area: %.2f\n",shape.Area())// 50.27

要点:接口变量内部存储了两部分信息:

  1. 类型信息— 底层是什么类型(Rectangle 还是 Circle)
  2. 值信息— 底层类型的实际数据

同一个shape变量可以先后指向不同类型的值,调用shape.Area()时,Go 根据shape当前的底层类型选择对应的方法实现。


知识点总结

知识点关键概念
接口定义type Name interface { 方法签名 },只声明不实现
隐式实现不需要implements,方法签名匹配即自动实现接口
多态函数接收接口参数,不同类型表现出不同行为
接口切片[]Shape可存放不同类型,统一遍历调用
接口赋值同一个接口变量可动态切换底层类型
接口内部存储 (类型, 值) 两部分信息,调用时根据类型选择方法

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询