Photo by Ash Edmonds on Unsplash

Go语言基础 — 接口

Golang Basic — Interface

Yunjie Ding

--

Duck Typing

说Go的接口就必须先了解duck typing的概念。很多其他的语言都支持这个概念。

首先上图的这个东西是鸭子吗?

鸭子的定义:

鸭子 英文名称:Duck。脊索动物门,脊椎动物亚门,鸟纲雁形目鸭科鸭属动物,是由野生绿头鸭斑嘴鸭驯化而来。是一种常见家禽。鸭是雁形目鸭科鸭亚科水禽的统称。是一种水、陆两栖动物。但不能在水中待太久,是卵生动物。中文学名鸭界动物界门脊索动物门亚 门脊椎动物亚门纲鸟纲亚 纲今鸟亚纲目雁形目

按照传统的定义,上面这个图肯定不是鸭子。但是按照duck typing的定义来说,上图这个东西是一只鸭子。因为他长得像鸭子。Duck Typing关注的是描述事物的外部行为而非内部结构。

但是严格来说Duck Typing的定义中要求动态绑定,但是Go是编译就绑定了,所以Go只能说是类似Duck Typing。

Python和C++中的Duck Typing

只有在运行的时候才知道传入的retriever有没有get,如果没有get方法,download的就会报错,但是如果download和retriever是两组不同的人开发。传入download的retriever必须有get方法这个信息通常会写在注释里。

同样C++也有类似的写法,然后C++可以做到编译的时候知道传入的retriever有没有get。同时这个信息还是需要写在注释里。

JAVA中的类似的东西

JAVA的这种做法确实很安全,传入的参数必须实现Retriever,也不用写注释了,也不会编译错误了。但是这已经不是Duck Typing,因为你必须实现Retriever接口。导致download不能实现多个接口。(比如read和write)

Go的Duck Typing

兼备Python的灵活性和JAVA的类型检查

接口的定义

Go语言中的接口由使用者定义

使用者

实现者

实际使用的时候

接口的值类型

接口内部

接口内部可以有实现者的类型和实现者

也可以用实现者的指针

检测类型

由于Go语言的所有类型都是值类型,所以在实际使用实现了接口的方法的时候r := mock.Retriever{"test"} 中的r除了保存了值,也保存了实现者的类型。

查看interace的类型有2中方法:

  • Type assertion

注意这里由于实现者里的方法是传的指针,所以r.(*mock.Retriever)也需要时指针。不然会报错。

  • Switch
  • 打印类型

空接口

interface{}代表空接口,可以代表任何类型。

假设有一个队列

如果定义为int的话当然只能往里面加int,但是如果您定义成空接口,就可以传任何值。

但是在往里面你传值的时候,你可以通过方法限定值得类型

这样的话如果q.push("abc")的话在编译的时候就能检测的错误。

还有一种方法是在append的时候做转换。

但是这样做的话就只能在执行的时候才能检查到错误了所以不推荐。

接口的组合

接口内部可以加入其他接口来进行组合。比如很多写入操作的参数都是reader或者writer

原生接口的例子

举个原生包的例子,比如写入文件。

使用者fmt.Fprintf接受一个io.writer,io.writer是一个接口,里面定义了一个write方法。

再看作为实现者的os.file构造体里面也实现了一个write方法,按照duck typing的规则,file实现了write方法,所以file也是一个writer,所以file也可以传给fmt.Fprintf

Go语言接口的好处

这样好处是显而易见的,我们拥有非常高的灵活性,同时保证在编译前就能检测到错误。尤其是在团队开发的时候,在其他编程语言当中,都是谁提供服务,谁提供接口。你需要调用我的服务,就必须声明你实现了我的接口。

而这在逻辑上实际是说不通的,服务实现者怎么会确切的知道服务使用者的具体需求呢?当需求发生变化的时候,服务实现者就需要考虑使用者的需求,从而设计接口。而从理论上来说,每一个服务的开发人员都应该专注于自己的服务。

而go语言不同。go语言的接口是非侵入式接口,只要调用者本身实现了该接口的全部方法,就默认实现了该接口(事实上也确实是实现了这个接口),而不需要显示的声明实现某个接口。这极大的方便了接口的调用,开发人员不必再需要苦想接口的粒度,只需要专注功能函数的实现就可以了。

--

--

Yunjie Ding
Yunjie Ding

Written by Yunjie Ding

Born in China, living in Tokyo, Opinion is my own.

No responses yet