Go 接口interface · 2023年4月12日 0

《10节课学会Go-08-Interface》【】

本文是全系列中第8 / 10篇:10节课学会Go

Interface

Go语言中,interface是一种类型,用于定义一组方法签名。一个实现了这些方法的具体类型被称为这个interface的实现类型。接口类型是一种抽象的类型,它不会暴露出所包含的具体值的内部结构和数据。

同时interface 类型可以代表任意类型的值,因此它可以用来定义不同类型的值。

定义接口

接口类型通常用于将具体类型的实现细节与实现类型的名称分离开来。它们可以帮助我们构建高度抽象的代码,使代码更加灵活、易于维护和扩展。同时,Go语言中的接口类型也提供了一种非常强大的面向对象编程机制,使得Go语言的面向对象编程变得更加自然和简单。

package main

import "fmt"

// Duck 接口类型 定义一组方法签名的集合
// 定义接口约定
type Duck interface {
  GaGaga()
  // ....
}

type DonaldDuck string

func (d DonaldDuck) GaGaga() {
  fmt.Printf("%s, ga ga gan", d)
}

type RubberDuck string

func (d RubberDuck) GaGaga() {
  fmt.Printf("%s, ga ga gan", d)
}

type Dog struct {
  Name string
  age  int
}

func (d Dog) GaGaga() {
  fmt.Printf("%s, ga ga gan", d.Name)
}

func main() {
  var d Duck

  d = DonaldDuck("  唐老鸭")
  d.GaGaga()

  d = RubberDuck("  小黄鸭")
  d.GaGaga()

  d = Dog{
    Name: "小狗",
    age:  5,
  }
  d.GaGaga()
}

以上代码定义了一个接口类型 Duck,并定义了三个实现该接口的具体类型 DonaldDuckRubberDuckDog

其中,DonaldDuckRubberDuck 都实现了 GaGaga() 方法,可以输出 xxx, ga ga ga 的字符串,而 Dog 类型也实现了 GaGaga() 方法,但是输出的是该狗的名字,而不是 ga ga ga

main 函数中,定义了一个 Duck 类型的变量 d,并将 DonaldDuckRubberDuckDog 类型的变量赋值给 d,这是因为这三个类型都实现了 Duck 接口,所以可以赋值给 Duck 类型的变量。

然后分别调用 dGaGaga() 方法,根据不同的类型,输出不同的字符串。

接口断言

接口断言是指从一个接口类型中提取出具体的值和类型信息的操作。在 Go 中,接口断言可以使用类型断言的方式进行实现。如果一个接口变量 x 的底层类型是 T 类型,我们可以使用 x.(T) 的方式对其进行类型断言,其中 .(T) 表示将 x 转换为 T 类型。

package main

import "fmt"

// 类型断言
// 断言 interface
func main() {
  var i interface{} = "hello"

  s := i.(string)
  fmt.Println(s)

  // 类型断言, 断言失败一般会导致panic的发生, 所以为了防止panic的发生, 我们需要在断言前进行一定的判断。
  // 如果断言失败, 那么ok的值将会是false
  // 如果断言成功, 那么ok的值将会是true, 同时s将会得到正确类型的值。
  s, ok := i.(string)
  fmt.Println(s, ok)

  f, ok := i.(float64)
  fmt.Println(f, ok)

  f = i.(float64) // 报错(panic)
  fmt.Println(f)
}

在代码中,变量 i 的类型为 interface{},表示它可以保存任何类型的值。然后使用 .(string) 进行类型断言,将其转换为字符串类型,并将结果赋值给变量 s

接下来使用类型断言和布尔值的组合形式,将 i 断言为字符串类型,并将结果分别赋值给 sok。由于 i 的实际类型是字符串类型,因此断言成功,ok 的值为 trues 得到了正确类型的值。

然后尝试将 i 断言为 float64 类型,这次断言失败,ok 的值为 falsef 的值为 0

最后尝试将 i 直接断言为 float64 类型,由于实际类型是字符串类型,所以这次断言会导致 panic 异常的发生。

为什么需要接口

  • 接口允许 Go 具有多态性, 在需要多态性的 Go 中使用接口。
  • 在可以传递多种类型的函数中,可以使用接口。
  • 接口还用于帮助减少重复/样板代码。

在需要动态类型参数的函数和方法的情况下,接口非常有用,例如接受任何类型值的 Println 函数。

参考

blog.knoldus.com/how-to

stackoverflow.com/quest

stackoverflow.com/quest

blog.boot.dev/golang/go

本文是全系列中第8 / 10篇:10节课学会Go
打赏 赞(0) 分享'
分享到...
微信
支付宝
微信二维码图片

微信扫描二维码打赏

支付宝二维码图片

支付宝扫描二维码打赏

文章目录