程序员Golang

golang interface

2017-03-21  本文已影响357人  大漠狼道

这个是常见的interface使用

type Reader interface {
Read(p []byte)(n int, err error)
}

func ValueOf(i interface{}) Value

var xxx interface{}

定义

interface是方法集

实现

例如:

type callback func() error

func (call callback)Error() string{
 err := call()
  return fmt.Srpintf("callback %v ", err)
}

那么callback也是个error,因为实现了error interface{},这里并没有显性的说明要实现error这个接口

对于第二点,也很有意思。有的时候,可能会出现这种类似场合:
两个第三方包的A,B类型都提供Format()方法,输入是interface类型,可能是A也可能是B,也可能是其他的,但是我们要format数据,怎么办呢?

switch typ := src.(type) {
  case A:
    // A.Format()
  case B:
    // B.Format()
  default :
    // do something
}
但是有个问题,如果以后类型不断增加,怎么办?
如果某个类型拥有某个方法集,那么就隐性的实现了某接口,这里共通的方法Format

func DemoFormat( src interface{}){
  type Formater interface{
    Format()
  }
  formater, ok := src.(Formater)
  if ok {
    // formater.Format()
  } else {
    // 没有实现Format(),另外处理
  }
}
github上的一个例子:
https://github.com/pkg/errors/blob/master/example_test.go#L176

还有个特例,Empty interface{},这个也是Type,他的类型是interface{},相当于空的方法集,也就是任何类型都是他的超集,即都实现了空接口。相当于javascript中的Any,任何类型都可以赋值给Empty interface{}

作为变量

var xxx interface{}
作为变量的时候,interface变量的底层有两个字段,一个是值,一个是method table,就是实现这个接口具体的方法集合。

type errorDemo struct{}
func (e errorDemo)Error()string{
  return "errorDemo error"
}
var err error = errorDemo{}

这个时候,err的值就是errorDemo,方法集就func(e errorDemo)Error()string
一个interface{}是有两个字段的,只有两个字段都是空都时候,才是nil interface{}

var err error = (*errorDemo)(nil)
猜猜 err ==nil 是true还是false,为什么?

对于interface变量,一定要记住他的底层是两个部分组成的,值和method table,反射就是根据这个来进行的。

发散

golang中type 可以Embeded。拥有某个类型,那就拥有这个类型的一切(霸道总裁- -!)。有的时候,就会出现A类型没有实现某个接口,但是嵌入A中的B类型实现了,这个时候也相当于A实现了该接口。
那么问题来了

  1. 如果A中还嵌入了C,C和B都实现了同样都接口I,那么会是什么情况?是调用C呢还是B呢还是别的?
  2. 如果A也实现了接口I呢?
  3. 根据1,2的理解,再考虑下,能不能实现重写,多态?
    可以留言,相互交流交流

写的生疏,要睡觉了。读者可以再想想interface的转换(cast),这个比较常用

延伸阅读

http://go-book.appspot.com/interfaces.html

原文 https://research.swtch.com/interfaces
译文 http://shareinto.github.io/2016/03/08/GoDataStructures-Interfaces/interfaces.html

参考文档

  1. Interface 结构: 这个是译文,原文很难打开 http://shareinto.github.io/2016/03/08/GoDataStructures-Interfaces/
    原文 https://research.swtch.com/interfaces
  2. golang io pkg
    https://golang.org/pkg/io/
  3. errors pkg
    https://github.com/pkg/errors
上一篇下一篇

猜你喜欢

热点阅读