当前位置: 首页 > 后端技术 > PHP

惊讶!goto语句是否使Go代码成为意大利面条?

时间:2023-03-30 00:29:26 PHP

大家好,我是炸鱼。Goto语句在社区的讨论中经常受到批评,认为它破坏了结构化程序设计和程序的抽象,有害而可怕。最早的观点来自于1968年,EdsgerDijkstra写了一封信《Go To Statement Considered Harmful》,表达了它是有害的观点。如下图所示:但是,但是,其实……Go是支持goto语句的。很多人不明白。喊得少的GoTeam其实加的多……今天,剑鱼就带大家看看。Goto语法Goto的语法格式如下:gotolabel......label:statement代码示例如下:packagemainimport"fmt"funcmain(){learnGoTo()}funclearnGoTo(){fmt.Println("a")gotoFINISHfmt.Println("b")FINISH:fmt.Println("c")}上面代码先在函数learnGoTo中输出a,然后转到gotoFINISH代码段,所以跳转直接到c的输出,所以b的输出代码就直接跳过了。输出:acGoto的危害Goto的危害的经典名称是:意大利面条代码,这是一个贬义词,指的是非结构化且难以维护的源代码。此类代码具有复杂且错综复杂的控制结构,导致程序流程在概念上类似于一碗意大利面条,扭曲且错综复杂。参考代码如下:INPUT"应该排序多少个数?";TDIMn(T)FORi=1TOTPRINT"NUMBER:";iINPUTn(i)NEXTi'计算:C=TE180:C=INT(C/2)IFC=0THENGOTOC330D=T-CE=1I220:f=EF230:g=f+CIFn(f)>n(g)THENSWAPn(f),n(g)f=f-CIFf>0THENGOTOF230E=E+1IFE>DTHENGOTOE180GOTOI220C330:打印"Thesortedlistis"FORi=1TOTPRINTn(i)NEXTi在上面的例子中,你可以看到goto语句可以在任何控制流中循环,你可能必须记住它的标签是什么并且它跳的地方。程序员也得想出各种各样的名字,比如:炸鱼哥、炸鱼哥、炸鱼友。命名灵感贫乏,容易混淆。在现实世界中业务代码的长期开发中,goto语句的滥用可能更为严重。Goto存在的意义GoSpec事实上,在Go中,Goto语句比其他语言有更严格的限制,用法在GoSpec《Goto statements》中有说明。规范要求在goto语句范围内不能有变量声明和其他动作,这是一种难闻的味道。下面的代码:gotoL//BADv:=3L:因为这会导致变量v的声明被跳过。同时要求代码块外的goto语句不能跳转到另一个代码块内的标号。下面的代码:ifn%2==1{gotoL1}forn>0{f()n--L1:f()n--}不能从if代码块跨作用域到for代码块。Go标准库的源码示例,参见Go标准库中的math/gamma.go源码,这是一个很好的例子。以下代码:forx<0{ifx>-1e-09{gotosmall}z=z/xx=x+1}forx<2{ifx<1e-09{gotosmall}z=z/xx=x+1}如果x==2{返回z}x=x-2p=((((x*_gamP[0]+_gamP[1])*x+_gamP[2])*x+_gamP[3])*x+_gamP[4])*x+_gamP[5])*x+_gamP[6]q=(((((x*_gamQ[0]+_gamQ[1])*x+_gamQ[2])*x+_gamQ[3])*x+_gamQ[4])*x+_gamQ[5])*x+_gamQ[6])*x+_gamQ[7]返回z*p/qsmall:ifx==0{returnInf(1)}returnz/((1+Euler*x)*x)}从上往下观察代码时,可以更快的识别goto语句,看到下面的标签跳转在实施和可读性方面是可以接受的。说到意义,可能有的同学会觉得。如果有问题,更有可能是没有limit,goto飞来飞去当然是不合理的。但实际上有两种思路,就像我们之前文章的读者提到的:你可以责怪程序员写意大利面条,或者你可以希望语言层面可以避免,这样你可以做得更好,而你没有需要每个新人。程序员要重新培养觉悟。Go也支持break中的标签跳转,这和goto的用法类似:Loop:for{select{...breakLoop}}GoTeam显然选择语言层面是为了避免goto的一些复杂场景,而只有一个goto跳转可以在一个代码块中执行,这样可以有更好的可读性并得到相应的值。总结一个新关键字的产生必须包括它的背景、原因和行为。如果一味地一刀切,孤独终究会得到解决。经过计算机行业近60年的goto知识和思考,大家已经意识到goto在任何控制流中跳来跳去是非常令人厌恶的。包括PHP这个世界上最好的语言,从5.3.0开始,也小心翼翼的加入了goto,也是有限制的,作用域是同文件同作用域。新的goto形式是对这种受限制的goto模式的探索。你怎么认为?如果你需要去某个地方,goto就是你要去的地方。——KenThompson的文章持续更新中,微信搜索【脑补炸鱼】即可阅读,本文已收录到GitHubgithub.com/eddycjy/blog,学习Go语言可以看Go学习地图和路线,欢迎Star提醒。Go书系列Go语言入门系列:初探Go项目实战Go语言编程之旅:深入使用Go做项目Go语言设计哲学:理解Go的原因与设计思维Go语言进阶之旅:进一步深入-深度Go源码推荐阅读Go设计哲学:少即是多,从何而来?为什么Go有两种声明变量的方式,有什么区别,哪种更好?