再过5分钟你就能了解 Go 语言的 Interfaces(接口)啦

160 阅读2分钟

1. 基本概念

  1. 接口本质是一种自定义类型
  2. 接口是一种特殊的自定义类型,其中没有数据成员,只有方法或者为空
  3. 一个类型可以实现多个接口,只要某个类型实现了接口的所有方法,那么我们就说该类型实现了此接口,该类型就可以当作是该接口来使用,该类型的值可以赋给该接口的值。
  4. 空接口interface{} (也可以使用 any 关键字来代替)没有任何方法,任何类型的值都可以赋值给它

2. 类型断言

2.1 value,ok 判断形式

value, ok := xx.(Type) 这种形式来判断

  1. interface{} 类型的变量是否是某一个类型
  2. interface{} 类型的变量是否实现了某一个接口

2.2 switch case 语句形式

package main

import (
	"strconv"
)

func str(f any) string {
	switch f.(type) {
	case int:
		return strconv.Itoa(f.(int))
	case int64:
		return strconv.FormatInt(f.(int64), 10)
	default:
		return "xxx"
	}
}

3. 检查是否实现接口

var _ 接口 = 类型{} 让类型实例化赋值给接口变量,编译器即会自动检测是否完成对接口的实现,这样有些错误就不用等到实际运行的时候才能发现了

4. 接口不等于nil

go 里面的 interface{} 实际上是包含两部分的,一部分是 type,一部分是 data,如果我们传递的 nil 是某一个类型的 nil, 那么 interface{} 类型的参数实际上接收到的值会包含对应的类型。 但如果我们传递的 nil 就是一个普通的 nil,那么 interface{} 类型参数接收到的 typedata 都为 nil, 这个时候再与 nil 比较的时候才是相等的

func test(i interface{}) {
 fmt.Println(reflect.TypeOf(i))
 fmt.Println(i == nil)
}

func main() {
 var b *int = nil
 test(b) // 会输出:*int false
 test(nil) // 会输出:<nil> true
}

5. 接口嵌套

type Writer interface {
    Write(p []byte) (n int, err error)
}

type Closer interface {
    Close() error
}

// 下面这个接口包含了 Writer 和 Closer 的所有方法
type WriteCloser interface {
    Writer
    Closer
}

WriteCloser 是包含了 WriterCloser 两个接口所有方法的新接口,对于某些只需要 Close 方法的地方,我们就可以用 Closer 作为参数的类型,写出更精确更细粒度的代码