Golang|04 面向接口
golang
中没有继承和多态,只支持封装,那些在C/C++/Java
中使用继承和多态实现的方式,在golang
中就可以使用接口来进行实现,golang
的接口比其他语言就灵活很多。
如下就是一个使用接口的例子:
type Traversal interface {
Traverse()
}
func main() {
traversal := getTraversal()
traversal.Traverse()
}
1. duck typing的概念
1.1 大黄鸭是鸭子吗?
- 传统类型系统:脊索动物门,脊椎动物亚门,鸟纲雁形目… 不是
duck typing
:是鸭子duck typing
概念:“像鸭子走路,像鸭子叫(长得像鸭子),那么就是鸭子”duck typing
描述事物的外部行为而非内部结构- 严格说
go
属于结构化类型系统,类似duck typing
, 不是动态绑定的,golang
是编译期绑定的。
1.2 Python中的duck typing
def download(retriever):
return retriever.get("www.baidu.com")
- 运行时才知道传入的
retriever
有没有get
- 需要注释来说明接口
1.3 C++中的 duck typing
template <class R>
string download(const R& retriever) {
return retriever.get("www.baidu.com")
}
- 编译时才知道传入的
retriever
有没有get
, 编写代码的时候不知道 - 需要注释来说明接口
1.4 Java 中的类似代码
<R extends Retriever>
String download(R r) {
return r.get("www.baidu.com")
}
- 不是
duck typing
,只有类似的代码 - 传入的参数必须实现
Retriever
接口, 这一点相比Python/C++
好 - 同时需要
Readable
,Appendable
怎么办?(apache polygene
)(实现多个接口时就不灵活了)
1.5 Go 语言的 duck typing
- 同时具有
Python
,C++
的duck typing
的灵活性 - 又具有
Java
的类型检查
2. 接口的定义和实现
2.1 接口的定义
使用者(download)→ 实现者(retriever)
- 接口由使用者定义
type Retriever interface {
Get(url string) string
}
func download(r Retriever) string {
return r.Get("http://www.baidu.com")
}
2.2 接口的实现
- 接口的实现是隐式的
- 只要实现接口里的方法
3. 接口的值类型
3.1 接口变量
- 实现者的类型
- 实现者的值或实现者的指针
3.2 接口变量里面有什么
- 接口变量自带指针
- 接口变量同样采用值传递,几乎不需要使用接口的指针
- 指针接收者实现只能以指针方式使用;值接收者都可
3.3 查看接口变量
- 表示任何类型:interface{}
- Type Assertion
- Type Switch
4. 接口的组合
type ReaderWriter interface {
Reader
Writer
}
5. 常用系统接口
- Stringer
- Reader/Writer
- 原文作者:Binean
- 原文链接:https://bzhou830.github.io/post/20180505Go%E9%9D%A2%E5%90%91%E6%8E%A5%E5%8F%A3/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。