[Go语言]为什么我喜欢Go的interface

Posted Golang语言社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Go语言]为什么我喜欢Go的interface相关的知识,希望对你有一定的参考价值。

原文链接

这篇文章主要是反驳老赵的一篇文章《为什么我不喜欢Go语言式的接口》,该文认为Go语言的interface有问题,因为不能保证行为特征。摘引如下:
简单地说,假如接口不能保证行为特征,则“面向接口编程”没有意义。
而Go语言式的接口也有类似的问题,因为Structural Typing都只是从表面(成员名,参数数量和类型等等)去理解一个接口,并不关注接口的规则和含义,也没法检查。忘了是Coursera里哪个课程中提到这么一个例子:
interface IPainter {

void Draw();
}
interface ICowBoy {

void Draw();
}
在英语中Draw同时具有“画画”和“拔枪”的含义,因此对于画家(Painter)和牛仔(Cow Boy)都可以有Draw这个行为,但是两者的含义截然不同。假如我们实现了一个“小明”类型,他明明只是一个画家,但是我们却让他去跟其他牛仔决斗,这样就等于让他去送死嘛。


我的观点:
原文的问题在于把C++/C#固有的思维方式硬搬到Go里,所以才得出了一个错误的结果说Go的interface有问题,导致把画家小明拉去和牛仔决斗。这个其实也是刚刚学习Go的C++/C#/Java程序员容易犯的错误。
其实Go里的思维方式不是这样的,interface并不是孤立存在的,它是type的抽象。而同一个事物/数据可以多个type。这个问题详见我的另外一篇博客文章《一人千面:谈谈Go语言中的type》。具体到这个问题我们来看看Go里面可以怎么样解决:
  1. type Painter interface {

  2. Draw()

  3. }

  4. type Cowboy interface {

  5. Draw()

  6. }

  7. type Xiaoming struct {

  8. }

  9. type XiaomingAsPainter Xiaoming

  10. func (p *XiaomingAsPainter) Draw() {

  11. //...

  12. }

  13. func main() {

  14. var xm Xiaoming

  15. var painter Painter = (*XiaomingAsPainter)(&xm)

  16. painter.Draw()

  17. }

复制代码

小明是个人(虽然这里实现为一个struct),画家只是他的一种身份,因此更好的方法是把画家的行为特性独立出来作为一个type,同时也是Painter接口的实现。如果想让他以画家的身份示人,只要把小明转换到画家的身份就可以(通过语句"var painter Painter =(*XiaomingAsPainter)(&xm)")。这样,小明还会被误认为是牛仔吗?显然没有这个可能性。

原文又说:
另一方面,“小王”也可以既是一个“画家”也是个“牛仔”,他两种Draw都会,在C#里面我们就可以把他实现为:
  1. class XiaoWang : IPainter, ICowBoy {

  2. void IPainter.Draw() {

  3. // 画画

  4. }

  5. void ICowBoy.Draw() {

  6. // 掏枪

  7. }

  8. }

复制代码

我的观点:
在Go里,如果小王既是画家又是牛仔,只要让小王同时具有牛仔和画家的身份(类型)就可以。
  1. type Xiaowang struct {

  2. }

  3. type XiaowangAsPainter Xiaowang

  4. func (p *XiaowangAsPainter) Draw() {

  5. //画画

  6. }

  7. type XiaowangAsCowboy Xiaowang

  8. func (p *XiaowangAsCowboy) Draw() {

  9. // 拔枪

  10. }

  11. func main() {

  12. var xw Xiaowang

  13. var painter Painter = (*XiaowangAsPainter)(&xw)

  14. painter.Draw()

  15. var cowboy Cowboy = (*XiaowangAsCowboy)(&xw)

  16. cowboy.Draw()

  17. }

复制代码

结论:C#的实现把不同类型的行为特性统统放到一个类里,而Go的实现把不同类型的行为特性独立开来,又从数据本质的层面把它们联系在一起(都是一个人的不同身份)。哪种实现类型之间耦合度小而类型内部的聚合性高?孰优孰劣,不是很清楚了吗?

微信名:Golang语言社区

微信ID:Golangweb

1、 点击历史信息,查看更多内容
2、 论坛网址: WwW.Golang.Ltd

3、 长按右侧二维码,关注Golang语言社区





以上是关于[Go语言]为什么我喜欢Go的interface的主要内容,如果未能解决你的问题,请参考以下文章

为什么 Go 是我最喜欢的编程语言(2017)[翻译]#IT人的升职加薪tips#

为什么用Go语言的普遍喜欢Python? | Go开发者年度调查报告

编程语言为什么我们更喜欢 Go 作为后端? Why we prefer Go for Backend

为什么我最喜欢的编程语言是 Go

go语言爬虫 - TapTap用户都喜欢些什么游戏

如何用go语言每分钟处理100万个请求