Go Interface接口初学者手册

 更新时间:2024年01月18日 09:36:22   作者:海上明月A  
这篇文章主要为大家介绍了Go Interface接口的基础用法实例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

Interface接口类型实现

接口是一组方法签名。如果一个类型在其上定义了给定接口的所有方法,则该类型 "实现" 了该接口。

在以下示例中,“形状” 必须能够返回其面积和周长。rect 和 circle 都满足该接口。

type shape interface {
  area() float64
  perimeter() float64
}
type rect struct {
    width, height float64
}
func (r rect) area() float64 {
    return r.width * r.height
}
func (r rect) perimeter() float64 {
    return 2*r.width + 2*r.height
}
type circle struct {
    radius float64
}
func (c circle) area() float64 {
    return math.Pi * c.radius * c.radius
}
func (c circle) perimeter() float64 {
    return 2 * math.Pi * c.radius
}

当一个类型实现一个接口时,它可以被用作该接口类型。

接口的实现是隐式的。

类型从不声明它实现了给定的接口。如果接口存在,并且类型定义了适当的方法,那么该类型会自动满足该接口。

Multiple Interfaces

在Go中,一个类型可以实现任意数量的接口。例如,空接口 interface{} 总是被每种类型实现,因为它没有要求。

Naming interface args

考虑以下接口:

type Copier interface {
  Copy(string, string) int
}

根据仅有的代码,你能推断出应该将什么类型的字符串传递给 Copy 函数吗?

我们知道函数签名期望两个字符串类型,但它们是什么?文件名?URL?原始字符串数据?另外,返回的那个整数到底是什么?

让我们添加一些有名的参数和返回数据,使其更清晰。

type Copier interface {
  Copy(sourceFile string, destinationFile string) (bytesCopied int)
}

好多了。现在我们可以看到期望是什么了。第一个参数是 sourceFile,第二个参数是 destinationFile,并返回了一个整数 bytesCopied

Type Assertions in Go

在Go中使用接口时,偶尔需要访问接口值的底层类型。您可以使用类型断言将接口转换为其底层类型。

type shape interface {
  area() float64
}
type circle struct {
  radius float64
}
// "c" is a new circle cast from "s"
// which is an instance of a shape.
// "ok" is a bool that is true if s was a circle
// or false if s isn't a circle
c, ok := s.(circle)
if !ok {
  // s wasn't a circle
  log.Fatal("s is not a circle")
}
radius := c.radius

Type Switches in Go

类型开关使得在一系列中执行多个类型断言变得很容易。

类型开关类似于常规的开关语句,但是情况指定的是类型而不是值。

func printNumericValue(num interface{}) {
  switch v := num.(type) {
  case int:
    fmt.Printf("%T\n", v)
  case string:
    fmt.Printf("%T\n", v)
  default:
    fmt.Printf("%T\n", v)
  }
}
func main() {
  printNumericValue(1)
  // prints "int"
  printNumericValue("1")
  // prints "string"
  printNumericValue(struct{}{})
  // prints "struct {}"
}

fmt.Printf("%T\n", v) 打印变量的类型。

Clean Interfaces

编写清晰的接口很难。坦率地说,每当在代码中处理抽象概念时,如果不小心,简单的事情很快就会变得复杂。让我们回顾一些保持接口清晰的经验法则。

 Keep Interfaces Small

如果你从这篇文章中只记住一点建议,那就是:保持接口的小巧!接口的目的是定义准确表示一个想法或概念所需的最小行为。

以下是标准 HTTP 包中的一个较大接口的示例,它很好地演示了定义最小行为的概念:

type File interface {
    io.Closer
    io.Reader
    io.Seeker
    Readdir(count int) ([]os.FileInfo, error)
    Stat() (os.FileInfo, error)
}

满足接口行为的任何类型都可以被 HTTP 包视为 File。这很方便,因为 HTTP 包不需要知道它处理的是磁盘上的文件,网络缓冲区还是简单的 []byte。

 Interfaces Should Have No Knowledge of Satisfying Types

接口应该定义其他类型需要满足的条件以成为该接口的成员。它们在设计时不应该知道任何恰好满足该接口的类型。

例如,假设我们正在构建一个描述定义汽车所需组件的接口。

type car interface {
  Color() string
  Speed() int
  IsFiretruck() bool
}

Color() 和 Speed() 完全有道理,它们是限定在汽车范围内的方法。IsFiretruck() 是一个反模式。我们强制所有汽车声明它们是否是消防车。为了使这种模式有任何意义,我们需要一个可能的子类型清单。IsPickup()IsSedan()IsTank()... 这会无休止地扩展。

相反,开发人员应该依赖于类型断言的本机功能,在给定汽车接口的实例时推导出底层类型。或者,如果需要子接口,可以这样定义:

type firetruck interface {
  car
  HoseLength() int
}

这个接口继承了 car 所需的方法,并添加了一个额外的必需方法,使车辆成为消防车。

Interfaces Are Not Classes

接口不是类,它们更加轻量。

接口没有构造函数或析构函数,不要求创建或销毁数据。

接口在本质上不是层次结构,尽管有语法糖可以创建接口,这些接口碰巧是其他接口的超集。

接口定义了函数签名,但不定义底层行为。创建接口通常不会在结构方法方,使代码更加干燥。例如,如果有五种类型满足 fmt.Stringer 接口,它们都需要有自己版本的 String() 函数。

以上就是Go Interfaces接口初学者手册的详细内容,更多关于Go Interfaces接口的资料请关注脚本之家其它相关文章!

相关文章

  • golang http连接复用方法

    golang http连接复用方法

    今天小编就为大家分享一篇golang http连接复用方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-07-07
  • Go并发编程实践

    Go并发编程实践

    并发编程一直是Golang区别与其他语言的很大优势,也是实际工作场景中经常遇到的。近日笔者在组内分享了我们常见的并发场景,及代码示例,以期望大家能在遇到相同场景下,能快速的想到解决方案,或者是拿这些方案与自己实现的比较,取长补短。现整理出来与大家共享
    2017-01-01
  • golang使用json格式实现增删查改的实现示例

    golang使用json格式实现增删查改的实现示例

    这篇文章主要介绍了golang使用json格式实现增删查改的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • Go 实现基于Token 的登录流程深度分析

    Go 实现基于Token 的登录流程深度分析

    Token 认证机制的核心思想是,服务端在用户登录时生成一个 Token,客户端在后续的请求中携带这个 Token,服务端通过验证 Token 的有效性来确认用户的身份,本文将带你深入探索基于 Token 的登录流程,这是一种更为灵活且适用于现代应用架构的认证方式
    2024-03-03
  • 创建Go工程化项目布局详解

    创建Go工程化项目布局详解

    这篇文章主要介绍了创建Go工程化项目布局详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • Go语言os包用法详解

    Go语言os包用法详解

    本文主要介绍了Go语言os包用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • 浅谈go中defer的一个隐藏功能

    浅谈go中defer的一个隐藏功能

    这篇文章主要介绍了浅谈go中defer的一个隐藏功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • Golang语言如何避免空指针引发的panic详解

    Golang语言如何避免空指针引发的panic详解

    简单地说go语言的指针类型和C/C++的指针类型用法是一样的,除了出去安全性的考虑,go语言增加了一些限制,这篇文章主要给大家介绍了关于Golang语言如何避免空指针引发panic的相关资料,需要的朋友可以参考下
    2022-01-01
  • 快速掌握Go语言正/反向代理

    快速掌握Go语言正/反向代理

    这篇文章主要介绍了快速掌握Go语言正/反向代理的相关资料,需要的朋友可以参考下
    2022-11-11
  • golang 比较浮点数的大小方式

    golang 比较浮点数的大小方式

    这篇文章主要介绍了golang 比较浮点数的大小方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05

最新评论