不少编程语言都有“goto”这个特性,但是,我们公司一个程序员看到我用goto,惊讶的说道:“你咋用goto?最好不要用goto!”,我问他为什么不能用,他也说不上来。
goto顾名思义,就是“去到哪里”的意思,在编程语言里,经常用来定位“锚点”,比如学过HTML基础的程序员应该都知道,HTML是有“锚点”这个概念的,有些网站的“回到顶端”就是使用“锚点标签”来实现的。
goto的用法
其他编程语言我不知道,至少在C#这门编程语言里,也是有goto的,定义“锚点”的时候,只需要使用“
”符号后面加一个“锚点”的名字就可以了,比如“FunEnd:”,但是要注意,后面要加一个英文的冒号,即“:”。
当我们想要代码跳到“锚点”所在的位置时,就需要使用goto了,比如“gotoFunEnd”,是不是很简单?
那么,goto到底有什么用?为什么很多程序员都不建议使用goto呢?
尽量不用goto的原因
goto的使用场景很简单,比如当代码中有很长一段逻辑,并且,如果逻辑是按照从上往下顺序执行,当执行到某个位置,我们不希望它继续执行,但是在代码的末尾又有统一的返回逻辑时,我们可以使用goto。
当然了,使用if语句也可以做到跟goto一样的效果,可我们如果在程序里写很多if语句,可能造成代码看起来不太优雅,所以,使用goto就比较合适了。
上面举的例子只是goto的一种用法,可以看我写的示例来理解goto的用法,其他用法您可以自行探索,这里就不多举例了!
为什么我们公司的同事看到我使用goto很惊讶,并且表示最好别用呢?
其实,我听过很多程序员都说过最好不要用goto,基本上他们也说不出来原因,只知道这就是程序员们口口相传的事情,传着传着就不让用了!
于是,我为了尝试搞清楚大家为什么都很排斥用goto,特地了解了下,基本上给出了以下几种说法。
第一种说法,goto是过去“面向过程”型编程语言时残留的写法,但是现在“面向对象”型编程语言的特性已经包含了“封装”这个特性,过去“面向过程”型编程语言的一些痛点已经被“面向对象”型编程语言给解决了,因此goto的好处就基本上可以被忽视了。
第二种说法在又增加了一种解释,比如说使用goto的话,会增加代码的复杂性,减小代码的可读性,简单得讲,goto因为能跳到代码的任何位置,因此在阅读代码的时候可能会导致空间错乱,影响阅读效率。
第三种说法在第一种和第二种说法的前提上,又增加了一种解释,那就是不可控!
所谓不可控很简单,其实很多代码的写法在程序员里面都被认为是不可控的写法,其他常见的不可控写法,我能想到的就有两个,分别是“死循环”和“递归”。
比如我们需要监视一个变量的状态,我们可以使用“死循环”来监视,有些“死循环”是需要控制它在合适的时机跳出去的,有些“死循环”则需要无限期执行,直到软件的运行生命周期终止,但如果在线程里面使用死循环或者在死循环里面使用线程的话,可能就会导致程序终止,但线程依然还在执行。
在这种情况下,想要控制“死循环”就需要代码写得非常谨慎,否则可能最后轻则导致CPU和内存过载,重则宕机。
其实,“递归”和goto所谓的“不可控”跟“死循环”的不可控原因是一样的,几乎只要控制不好,就可能导致陷入一个无限循环。
结语
但是,所谓的“不可控”,我觉得,只是那些在“不可控”场景下吃过亏的程序员的自我解释的理由罢了,实际上想要做到可控,代码写严谨一些就行了!
比如上述三个例子,就顺利结束!
简单点说,如果真不可控了,那么说明代码写得有问题。
最后,我觉得goto不是不能用,而是既要保证不影响代码阅读(比如尽量让goto向下跳而不向上跳),又要保证可控,那goto依然能用。
如果goto真的像一些程序员说得那么不堪,那goto应该早就被各大编程语言设置成“过时”方法了,而很多编程语言里很多旧的函数都已经被标为“过时”了,可goto依然健在,足以说明它没那么不堪