[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里面可以怎么样解决:
复制代码 小明是个人(虽然这里实现为一个struct),画家只是他的一种身份,因此更好的方法是把画家的行为特性独立出来作为一个type,同时也是Painter接口的实现。如果想让他以画家的身份示人,只要把小明转换到画家的身份就可以(通过语句"var painter Painter =(*XiaomingAsPainter)(&xm)")。这样,小明还会被误认为是牛仔吗?显然没有这个可能性。原文又说: 另一方面,“小王”也可以既是一个“画家”也是个“牛仔”,他两种Draw都会,在C#里面我们就可以把他实现为:
复制代码 我的观点:在Go里,如果小王既是画家又是牛仔,只要让小王同时具有牛仔和画家的身份(类型)就可以。
复制代码 结论:C#的实现把不同类型的行为特性统统放到一个类里,而Go的实现把不同类型的行为特性独立开来,又从数据本质的层面把它们联系在一起(都是一个人的不同身份)。哪种实现类型之间耦合度小而类型内部的聚合性高?孰优孰劣,不是很清楚了吗? |
微信名:Golang语言社区
微信ID:Golangweb
1、 点击历史信息,查看更多内容
2、 论坛网址: WwW.Golang.Ltd
3、 长按右侧二维码,关注Golang语言社区
以上是关于[Go语言]为什么我喜欢Go的interface的主要内容,如果未能解决你的问题,请参考以下文章
为什么 Go 是我最喜欢的编程语言(2017)[翻译]#IT人的升职加薪tips#
为什么用Go语言的普遍喜欢Python? | Go开发者年度调查报告