Go语言学习之接口使用的示例详解

 更新时间:2022年11月24日 09:05:42   作者:孙琦Ray  
Go语言并没有类的定义,接口可以说Go语言最接近于类的实现方式,但是更轻量。本文将通过一些简单的示例和大家介绍下Go语言中接口的使用,感兴趣的可以学习一下

正如前文提到,Go语言并没有类的定义,接口可以说Go语言最接近于类的实现方式,但是更轻量。对于接口的学习,如果从原理层面理解学习起来比较慢,所以建议先从代码使用维度进行理解,最终回归到原理层面加深理解。

需求与分析

假设我们有一组图形,需要计算每个图形的面积,并计算他们的面积之和。那么最简单的方法就是分别计算他们的面积,并进行相加,我们来尝试实现一下。

不使用接口的实现

在这个代码实现中,我们需要将两种不同形状,矩形(rect)和圆形(circle)的面积求和,因此我们定义了如下内容:

  • 两个结构体,矩形是长和宽,圆形是半径
  • 分别实现了两个求面积的方法area(),矩形的面积等于长乘以宽,而圆形面积则是半径的平方乘以Pi
  • 在求和部分,我们直接定义了一个float64的数组,将面积直接存入该数组中
  • 通过循环进行求和

虽然上述方式能够满足我们的需求,但是如果我们需要增加一个计算周长的方法时,我们的代码会变得非常冗余并且可读性变差,因此我们用接口尝试来改造我们的代码。

package main

import (
    "fmt"
    "math"
)

type rect struct {
    width float64
    height float64
}

func (r rect) area() float64 {
    return r.width * r.height
}

type circle struct {
    radius float64
}

func (c circle) area() float64 {
    return math.Pi * c.radius * c.radius
}

func main() {
    var areaSum float64
    
    // Intial circle and rect struct type
    c1 := circle{2.5}
    r1 := rect{3, 4}
    
    // Save all area results into an array
    shapeAreas := []float64{c1.area(), r1.area()}
    
    // Sum all area together
    areaSum = 0
    for _, area := range shapeAreas {
        areaSum += area
    }
    
    fmt.Printf("Sum area = %v\n", areaSum)
}

使用接口的实现

相较于上述代码,我们做了如下优化:

  • 定义了一个新的interface shape,包含一个area()方法,即实现了area()的struct,就实现了shape接口
  • 在结构体定义,area()计算部分我们并没有修改
  • 在主函数中,我们重新定义了一个类型为shape interface的数组,该数组中无须再计算area(),只需要将两个不通类型存放在该数组中
  • 在循环过程中,我们直接调用每个shape interface中的area()方法,即可完成面积求和
package main

import (
    "fmt"
    "math"
)

// Define a new interface, contain a method define and type is float64
type shape interface {
    area() float64
}

type rect struct {
    width float64
    height float64
}

func (r rect) area() float64 {
    return r.width * r.height
}

type circle struct {
    radius float64
}

func (c circle) area() float64 {
    return math.Pi * c.radius * c.radius
}

func main() {
    var areaSum float64
    
    // Intial circle and rect struct type
    c1 := circle{2.5}
    r1 := rect{3, 4}
    
    // Previous: Save all area results into an array
    // Previous: shapeAreas := []float64{c1.area(), r1.area()}
    
    // Define an array with new shape interface
    shapes := []shape{c1, r1}
    
    // Previous: Sum all area together
    areaSum = 0
    // Previous: for _, area := range shapeAreas {
    // Previous:     areaSum += area
    // Previous: }
    
    // Implement a new loop
    for _, shape := range shapes {
        areaSum += shape.area()
    }
    
    fmt.Printf("Sum area = %v\n", areaSum)
}

接口作为函数参数

进一步优化代码,我们将接口作为参数,在主函数中调用时,只需要传入相应类型就会自动根据类型调用相应的计算面积的方法。

package main

import (
    "fmt"
    "math"
)

// Define a new interface, contain a method define and type is float64
type shape interface {
    area() float64
}

type rect struct {
    width float64
    height float64
}

// NOTE: 接口类型为rect
func (r rect) area() float64 {
    return r.width * r.height
}

type circle struct {
    radius float64
}

// NOTE: 接口类型为circle
func (c circle) area() float64 {
    return math.Pi * c.radius * c.radius
}

func getArea(s shape) float64 {
    return s.area()
}

func main() {
    var areaSum float64

    // Intial circle and rect struct type
    c1 := circle{2.5}
    r1 := rect{3, 4}

    // Previous: Save all area results into an array
    // Previous: shapeAreas := []float64{c1.area(), r1.area()}

    // Define an array with new shape interface
    shapes := []shape{c1, r1}

    // Previous: Sum all area together
    areaSum = 0
    // Previous: for _, area := range shapeAreas {
    // Previous:     areaSum += area
    // Previous: }

    // Implement a new loop
    for _, shape := range shapes {
        areaSum += getArea(shape)
    }

    fmt.Printf("Sum area = %v\n", areaSum)
}

到此这篇关于Go语言学习之接口使用的示例详解的文章就介绍到这了,更多相关Go语言接口内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Golang异常处理之defer,panic,recover的使用详解

    Golang异常处理之defer,panic,recover的使用详解

    这篇文章主要为大家介绍了Go语言异常处理机制中defer、panic和recover三者的使用方法,文中示例代码讲解详细,需要的朋友可以参考下
    2022-05-05
  • Go 语言中 20 个占位符的整理

    Go 语言中 20 个占位符的整理

    这篇文章主要介绍了Go 语言中 20 个占位符的整理,看完本篇文章讲学会什么是占位符?哪些函数支持?如何使用占位符?不同的占位符的作用?配合占位符的几个标记符号用法?
    2021-10-10
  • Go语言eclipse环境搭建图文教程

    Go语言eclipse环境搭建图文教程

    这篇文章主要介绍了Go语言eclipse环境搭建的方法,结合图文形式详细分析了在eclipse环境下开发Go语言所涉及的组件下载、安装及相关设置方法,需要的朋友可以参考下
    2016-07-07
  • golang 实现时间戳和时间的转化

    golang 实现时间戳和时间的转化

    这篇文章主要介绍了golang 实现时间戳和时间的转化操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • Go打包二进制文件的实现

    Go打包二进制文件的实现

    这篇文章主要介绍了Go打包二进制文件的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • Go gin框架加载Html模板文件的方法

    Go gin框架加载Html模板文件的方法

    这篇文章主要介绍了Go gin框架加载Html模板文件的方法,Gin框架没有内置静态文件服务,但可以使用gin.Static或gin.StaticFS中间件来提供静态文件服务,文中有相关的代码示例供大家参考,需要的朋友可以参考下
    2024-03-03
  • 一文教你如何快速学会Go的struct数据类型

    一文教你如何快速学会Go的struct数据类型

    结构是表示字段集合的用户定义类型。它可以用于将数据分组为单个单元而不是将每个数据作为单独的值的地方。本文就来和大家聊聊Go中struct数据类型的使用,需要的可以参考一下
    2023-03-03
  • Go语言并发爬虫的具体实现

    Go语言并发爬虫的具体实现

    本文主要介绍了Go语言并发爬虫的具体实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • Go通过goroutine实现多协程文件上传的基本流程

    Go通过goroutine实现多协程文件上传的基本流程

    多协程文件上传是指利用多线程或多协程技术,同时上传一个或多个文件,以提高上传效率和速度,本文给大家介绍了Go通过goroutine实现多协程文件上传的基本流程,需要的朋友可以参考下
    2024-05-05
  • Golang 处理浮点数遇到的精度问题(使用decimal)

    Golang 处理浮点数遇到的精度问题(使用decimal)

    本文主要介绍了Golang 处理浮点数遇到的精度问题,不使用decimal会出大问题,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02

最新评论