还记得当年老师不让你使用的GOTO语句吗?

先来一堆废话

最近正在开发案例模块包含了多重嵌套循环,于是听到了下面很有意思的一段对话:

Gabriel_he:嘿man,有没有办法从多重循环中直接跳出的方法。
HoldTheBabyToGoToSchool:好像没得,只能挨着判断。
Gabriel_he:噢,其实可以用goto语句。
HoldTheBabyToGoToSchool:goto语句老师不是说不要使用啊。
Gabriel_he:那是对于大学生或者菜鸟程序员是这样的,对于那些5、10年的老司机来说完全不是问题,问题是看你怎么用它。

我在旁边默默想了想好像是这么回事,大一上C语言课程的时候就接触到GOTO语句,依稀记得老师也是告诉我们GOTO语句会造成程序的混乱,可读性不强,是个坏习惯,写法又烂,最好不要使用。这个问题从我接触到GOTO的第一天起就没有想清楚过,或许根本没有花心思去想,直到听到上面的对话,让我又重新燃起对GOTO语句了解的欲望。

什么是GOTO?

GOTO语句也称为无条件转移语句,其一般格式如下:
(语句标号)loop:for(i=0;i<10;i++){
//todo
}
goto loop;

GOTO语句的语义是改变程序流向, 转去执行语句标号所标识的语句。

该不该使用?

在整个编程语言发展的过程中,对goto语句到底该不该使用,一直都是众说纷纭,大致可以分为以Donald Ervin Knuth为首的支持派(GOTO语句使用起来比较灵活,而且有些情形能提高程序的效率。若完全删去GOTO语句,有些情形反而会使程序过于复杂,增加一些不必要的计算量。)和以Edsger Wybe Dijkstra为首的反对派(GOTO语句使程序的静态结构和动态结构不一致,从而使程序难以理解,难以查错。), 后者在一封信中指出Go To Statement Considered Harmful。

直到1974年,D·E·克努斯对于GOTO语句争论作了全面公正的评述,其基本观点是:不加限制地使用GOTO语句,特别是使用往回跳的GOTO语句,会使程序结构难于理解,在这种情形,应尽量避免使用GOTO语句。但在另外一些情况下,为了提高程序的效率,同时又不至于破坏程序的良好结构,有控制地使用一些GOTO语句也是必要的。

后来,G·加科皮尼和C·波姆从理论上证明了:任何程序都可以用顺序、分支和重复结构表示出来。这个结论表明,从高级程序语言中去掉GOTO语句并不影响高级程序语言的编程能力,而且编写的程序结构更加清晰。

场景分析

  • 多重循环跳出问题
    由于不同的编程语言对GOTO语句的支持情况不同,下面只以C#进行举例:
    for(int i=0;i<10;i++)
    {
    for (int j=0;j<5;j++)
    {
    //todo 直接跳出整个嵌套循环
    }
    }

      方法一:goto
      
      for(int i=0;i<10;i++)
      {
        for (int j=0;j<5;j++)
        {
          goto:finish;
        }
      }
      finish:Console.WriteLine('End The Loop');
    
      方法二:flag,教条式写法
      bool flag=false;
      for(int i=0;i<10;i++)
      {
        for (int j=0;j<5;j++)
        {
          flag=true;
          break;
        }
        if(flag)
        {
          break;
        }
      }
      大家看了上面两种写法后还有没有可能想出其他的方法,下面我来给出第三种比较风骚的写法(纯属搞来耍)
      方法三:
       try
        {
          for(int i=0;i<10;i++)
           {
              for (int j=0;j<5;j++)
              {
                throw new Exception();
              }
            }
        }
       catch(Exception ex)
        {
            Console.WriteLine('太骚了');
        }
    
      在JAVA、Javascript(goto为保留关键字)里没有提供goto语句,但是可以通过标签(我个人理解为受限制的GOTO语句)的写法达到GOTO语句的效果。
      loop:for (var i=0;i<10;i++)
              {
                  for(var j=0;j<5;j++)
                  {
                     break loop;
                  }
              }       
    
  • 关于if-else
    在我们的实际工作中经常会有对于if-else的以下使用场景:
    if(doSomething())
    {
    if(doSomething1())
    {
    if(doSomething2())
    {
    .......
    }
    }
    else
    {
    }
    }
    else
    {
    }
    那么对于以上这种情况,我们是否可以考虑GOTO语句在多重条件判断下使用呢?下面看看使用GOTO语句的方式
    if(!doSomething())
    {
    goto error;
    }
    if(!doSomething1())
    {
    goto error;
    }
    ........
    是不是明显要清晰很多

感受

GOTO语句的使用还需要回归到具体场景,具体团队中去,不要偏激的认为GOTO语句完全不能使用或者一看到GOTO语句就认为这个代码太垃圾,也不要认为用了GOTO语句的代码就是好味道。

就拿我们来说,除了上面的两种方式外我还真没想到需要使用GOTO语句的场景,大多数高级语言都自带垃圾回收机制,不用开发者去考虑资源的回收和释放,换句话说现在的高级程序语言能够找到很好的替代方案,即使在某些情况下代码没有那么优雅,但是它能够保证程序的可靠性和可读性。

在操作系统或底层硬件开发上,有些使用的C或者汇编,在某些场景下使用GOTO效率还会更高,同时像汇编没有if-else,while,都是有条件和无条件转移,那么开发者对goto的使用自然了熟于心经验使然。

总之,GOTO语句尽量少用,大多数情况下都是可以通过结构化编程方式解决问题,即便你或你的团队非要使用需要在初期明确使用的标准(在同一个函数中转移,保证是顺序执行等)和场景并添加相应的注释。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,612评论 5 471
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,345评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,625评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,022评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,974评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,227评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,688评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,358评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,490评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,402评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,446评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,721评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,802评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,013评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,504评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,080评论 2 341

推荐阅读更多精彩内容