黑马程序员golang
在工作的一天,我们在工作聊天室中讨论Go编程语言。 有一次,我在同事的幻灯片上发表了评论,说了一些类似的话:
“我认为这就像成为Go程序员的七个阶段中的第三阶段。”
当然,我的同事们想知道其余的阶段,因此我简要地概述了它们 。 在这里,随着更多的上下文而扩展,是成为Go程序员的七个阶段。 看看您是否能在这条路上看到自己。
阶段1:您相信可以让Go做面向对象的编程
进行一次环游之后 ,您开始思考“现在,如何使这种语言表现得更像面向对象的语言...?” 毕竟,您已经习惯了这些东西。 您想要制作健壮的代码。 您想要多态。“一定有办法!” 您说了,然后发现struct embedding 。 它使您可以巧妙地将方法从封闭对象委托给嵌入式对象,而不必重复执行代码。 大!
当然,这是不正确的。 结构嵌入仅允许您委派方法调用。 即使看起来您正在执行多态方法分派,该关系也不是IS-A 。 它是HAS-A ,因此方法调用的接收者不是封闭的对象:接收者始终是方法调用委托到的嵌入式对象。
您不要在Go中进行面向对象的编程。 期。
阶段2:您相信goroutines将解决您的所有问题
承诺可以让您轻松运行并发代码(这是通过goroutines实现的) ,诱使您进入Go! 您所需要做的就是使用go关键字,几乎可以使任何同时运行的函数或方法调用。 因此,您很自然地希望通过使尽可能多的代码并行运行来最大化代码的效率。 并且由于您通过调用函数来自动创建goroutine来隐藏了这一事实,因此调用者甚至不需要意识到这一点。
是的,所以这可能会使您的代码稍微复杂一点,但是看起来,现在所有内容都可以同时运行!
Go允许您在不牺牲效率的情况下创建数百万个goroutine,但实际上不应仅仅因为可以就使用goroutine。 并发代码难以维护和调试比只是在单个线程中流动的代码。 我的意思是,您是否认真考虑过一次从多个goroutine中访问共享对象时是否真的正确同步了? 您确定执行顺序绝对正确吗? 您是否真的检查了不再需要这些goroutine的情况?
Goroutine仅在必要时才最好使用,除非您的要求指示您要在内存中执行任何操作或执行此类操作,否则切勿放弃使用旧的多进程模型。
最后,尽量不要在用户背后生成goroutines,尤其是在编写库时。 使用go呼叫的显式呼叫通常会给用户带来更大的灵活性和力量。
Goroutines仅将您带走。 仅在确实有意义时才使用它们。
阶段3:您认为接口可以解决您的所有问题,而不是面向对象的编程
在对无法使对象表现出多态性的幻想破灭之后,您突然意识到interfaces提供的功能 。 接口允许您描述API; 必须有一种方法来使用它来编写更健壮的代码。
因此,现在编写库时,就可以为所有对象定义接口。 您仅导出接口并具有私有结构,因此封装是完美的。 它还应该使您在切换基础实现上具有更大的灵活性,因为现在您已经成功地将API与实现分离了。
接口确实为您提供了强大的功能,但这并不是最终的解决方案。 从面向对象编程的角度来看,它仍然没有提供真正的多态性。 接口还只能定义API,并且不能将任何数据与其关联,这也使您受到限制。
同样,尽管在某些合理的情况下,仅导出接口而不是具体结构是有意义的,但实际上这不应该是您的默认操作模式。 当接口很小时(与描述为对象定义的方法的完整列表相反),接口是最佳的。 同样,如果您不小心,则将不得不编写大量额外的代码来实现接口,或者编写需要大量类型断言的代码。
为了充分利用接口,仅在要使某些类型可互换时才应使用它们。
阶段4:您相信频道会解决您的所有问题
在花了很多时间思考如何弯曲Go以便按自己的方式工作之后,现在您正在寻找缺少的东西,它将使一切正常工作。 “等等,还有频道 !”
通道隐式地正确处理并发访问。 您相信到目前为止,通过巧妙地使用通道来处理同步,返回值(将来/承诺)以及使用具有各种通道的select语句进行流控制,您应该能够解决许多障碍。
同样,通道是非常有用的,但是它们仅与最初目的一样有用,即提供一个在goroutines之间传递值的原语。
我相信您会发现使用通道的很多Go习惯用法:用于超时,阻止I / O,同步技巧等。但是同样, 由于通道是并发构造,因此滥用它们将导致更复杂,更难调试的代码。
第5阶段:您现在认为Go并不像人们声称的那样强大
“为什么?!为什么编写Go代码这么痛苦?它不允许我按照自己的方式编写代码。”
你很沮丧 没有多态性。 并发很难。 渠道不能解决您的问题。 您甚至都不了解Go为何存在。 您感觉好像被剥夺了其他语言提供的所有出色工具和构造。
您认为绝对有必要使用更强大的工具来表达抽象思想。 去只是不削减它。
Go无疑是固执己见的。 我来自Perl,有一段时间我不敢相信Go的局限性。 所以是的,我知道您是否感到沮丧。
但这是因为语言确实有限制,还是 是否因为您在尝试使语言按您应有的方式工作而不考虑语言作者的意图?
阶段6:您意识到1-5阶段只是您的想象力
在某个时候,您会勉强决定根据大多数标准库的编写方式来编写Go代码。 您还放弃尝试变得聪明,并开始编写简单的代码。
然后想到了:您只是不想接受Go方式。
一切开始变得有意义。
认真地说,学习Go确实需要一些学习。 我不得不稍微学习一下面向对象的程序设计,并接受这样一个事实,即不管该语言可以为您提供多少有用的工具,编写并发代码对于普通人来说都太困难了。 我还不得不学会使用异常。
我没有与Go的作者核实,所以这只是我的看法,但是我相信该语言的重点是使开发人员更难编写复杂的代码。 它为您提供了编写执行复杂任务的代码的足够资源,但是通过删除某些关键工具,最终编写的代码变得更简单,更难以混淆。
一旦我决定接受这些功能和结构,编写Go代码就变得更加容易,而且绝对会变得更加有趣。
阶段7:您现在处于和平状态
您已经接受了Go方式。 现在,您可以在Go中编写所有内容,包括通常使用Perl / Ruby / Python的内容。 您意识到如果err!= nil不再困扰您。 仅在必要时才使用goroutine和通道。
您会感觉到它的光彩,而当您意识到它的怜悯使您可以用如此雄伟的语言编写代码时,就会哭泣。
恭喜你 现在您是Go程序员。
尽管这听起来有些ch舌,但这些是我习惯于Go时遇到或遇到的实际问题。 也许您同意,也许您不同意,但是第六阶段实际上对我来说就是这样。 我最终放弃了尝试使Go像我希望的那样工作,并决定写Go告诉我的方法 。 听起来很愚蠢,但是在那之后,事情真的开始变得有意义了。
希望新的Gophers能够减少浪费的时间来思考如何弯曲语言并感到沮丧。 玩得开心!
黑马程序员golang