V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
me15000
V2EX  ›  分享发现

有人用 goto 语句么?我是用它代替递归

  •  1
     
  •   me15000 · 2017-10-24 16:35:17 +08:00 · 10773 次点击
    这是一个创建于 2594 天前的主题,其中的信息可能已经有所发展或是发生改变。
    
    //递归
    void repeat(c) {
    
    	
    		//需要重复的代码
    	
    
    		if (xx) {
    			 repeat(xx);
    		}
    
    }
    
    //goto 代替递归
    void repeat(c) {
    
    	loop:
    		//需要重复的代码
    	
    
    		if (xx) {
    			goto loop;
    		}
    
    }
    
    
    
            //一个采集程序
            public void Run(string listurl)
            {
                using (var wc = new WebClient())
                {
                    loop:
    
                    string html = Encoding.GetEncoding("utf-8").GetString(wc.DownloadData(listurl));
                    var doc = new HtmlDocument();
                    doc.LoadHtml(html);
                    var nodes = doc.DocumentNode.SelectNodes("//ul[@id=\"data_list\"]/li/div/a");
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        var node = nodes[i];
                        string link = "http://www..cn" + node.Attributes["href"].Value;
                        string title = node.SelectSingleNode("span[@class=\"sTit\"]").InnerText;
                        Save(title, link);
                    }
                    var nextnode = doc.DocumentNode.SelectSingleNode("//div[@class='page mb clearfixs']/em/following-sibling::a");
                    if (nextnode != null)
                    {
                        listurl = "http://www..cn" + nextnode.Attributes["href"].Value;
                        goto loop;
                    }
                }
            }
    
    第 1 条附言  ·  2017-10-24 18:03:57 +08:00

    之前用递归是因为很多时候需要遍历一个无限极分类, 还有就是采集的时候,需要一直下一页下一页,页数很多的时候,递归性能差 在使用goto 之前,我也尝试过 for 和 while,但是略显麻烦 所以我想到了goto ,用了之后,感觉很简约方便

          //一个采集程序,使用递归形式
            public void Run(string listurl)
            {
                using (var wc = new WebClient())
                {
    
                    string html = Encoding.GetEncoding("utf-8").GetString(wc.DownloadData(listurl));
                    var doc = new HtmlDocument(html);
                    var nextnode = doc.DocumentNode.SelectSingleNode("//div[@class='page mb clearfixs']/em/following-sibling::a");
                    if (nextnode != null)
                    {
                        var nexturl = nextnode.Attributes["href"].Value;
    
                        Run(nexturl); ///递归采集
                    }
                }
            }
    
    
          //一个采集程序,使用了goto
            public void Run(string listurl)
            {
                using (var wc = new WebClient())
                {
                    loop:  //////定义 goto lable 作为跳转标记
    
                    string html = Encoding.GetEncoding("utf-8").GetString(wc.DownloadData(listurl));
                    var doc = new HtmlDocument(html);              
                    var nextnode = doc.DocumentNode.SelectSingleNode("//div[@class='page mb clearfixs']/em/following-sibling::a");
                    if (nextnode != null)
                    {
                        listurl = nextnode.Attributes["href"].Value;
    
                        goto loop;///////////////////////这里是goto 到 loop
                    }
                }
            }
    
    
    //使用while
    public void Run(string listurl) {
    	using(var wc = new WebClient()) {
    		while (true) {
    			string html = Encoding.GetEncoding("utf-8").GetString(wc.DownloadData(listurl));
                            var doc = new HtmlDocument(html);
    			var nextnode = doc.DocumentNode.SelectSingleNode("//div[@class='page mb clearfixs']/em/following-sibling::a");
    			if (nextnode != null) {
    				listurl = nextnode.Attributes["href"].Value;
    			} else {
    				break; //跳出while
    			}
    
    		}
    	}
    }
    
    第 2 条附言  ·  2017-10-26 08:54:53 +08:00
    技术够用就行,达到目的就行,更多的时候是为了实现需求解决问题,语法、技术细节这些都不是核心问题,一个简单嘚 goto 都能扯出这么多问题,还让人编程么?如果每个技术细节都这样深究,那真不好做了,我只是用个 goto 而已,地球不会炸的,起码我得到的结果是,程序简洁明了,性能也很好,并不难懂,没出什么问题,这就是我要的
    第 3 条附言  ·  2017-10-26 09:58:09 +08:00
    后面的回复已经偏离我表达的初衷
    要不我建个群来喷吧: @all
    128 条回复    2017-10-27 09:04:44 +08:00
    1  2  
    msg7086
        101
    msg7086  
       2017-10-26 09:30:47 +08:00
    对了,举报就是幼稚园学生?打 110 报警的学生就该被警告处分咯?(/滑稽

    不举报管理员那怎么办,把你喷到删号为止?
    找管理员那是给你台阶下,以后说起来你可以自称是坛友嫉妒你的才华而举报你,而不是因为帖子太水被人喷到气炸,对不对。
    zhujinliang
        102
    zhujinliang  
       2017-10-26 09:39:59 +08:00
    难难难,道德玄,不对知音不可谈。对了知音谈几句,不对知音枉费舌尖。
    ryd994
        103
    ryd994  
       2017-10-26 09:44:14 +08:00 via Android
    #90 @msg7086 说的部分。我也补充一个吧。我虽然是个 new grad。好歹拿到了微软 offer,fb 也约了面试。微软一面就是 bfs,二面就是个 dfs。该上循环上循环,该上递归上递归。

    @facetest goto 正确使用很好用,很强大
    但楼主这不是正确的例子。你有认真看高票回答么?“ while it is always possible to plead exception, it usually (in my experience and humble opinion) isn't worth the risks.”

    @me15000 这样用就是容易出 bug 啊,而且出了 bug 没法修。也就你自己现在知道这个 goto 是干什么的。别人,甚至是几个月后的自己,都不可能知道。
    我当你面举报,有什么 man 不 man 的?
    我不会用 goto ?笑话,我汇编也写了不知多少。你现在和我说 goto ?所有的控制流程,所有的函数调用,到汇编里都是跳转和分支。又不是没写过。

    @introom #50 “楼主没有放弃用 goto 是好事情”他这个例子就是不该用的例子。不能用“ goto 正确使用的时候很强大”来证明“小白用 goto 没有坑”。事实就是不正确使用的 goto 是大坑。而且大多数新手不能正确使用。
    me15000
        104
    me15000  
    OP
       2017-10-26 09:50:00 +08:00
    @msg7086 你说话的方式不是很讨人喜欢,明显在喷人么,

    引用你的话:

    没有 VS,随便开了个编辑器手打的,而且 C#大概五六年没写了,如果有错请见谅。
    另外,你知道 Encoding.UTF8 吗?

    你这不是明显吹嘘自己伤害别人么?还强词夺理,现实中你敢这样说么?

    谈不上讨厌做技术的人我本身也是做技术的,某些方面我还很崇拜,只是很多做技术太深入了的人,比如您,一股子老师傅教条式的感觉,咱有点互联网精神好不好,陈旧、教条,不是互联网所推崇的,互联网推崇探索,追求 - “简”,而我这样写的理念正是为了“简”,你那一套套理论,是专门来扼杀我们这些想法,这让人很崩溃好不好,本来就是个无伤大雅的 goto 来替代递归的一种解决方法,我想表达的是:goto 还是有好用的时候,而你们偏偏来攻击我,后面的话我不想说了,反正说这些吧我没生气,我认为你们这些人都挺有意思,技术出身的人,都有一种浓厚的 说不出的感觉,就是不够大气,不够豁达,我同时也坚信像我这种如果在你身边做事情,肯定不好过,
    我觉得你这样也好也不好,你看你也太认真了,把自己的信息透露了那么多来论证你是对的,你是好的
    ryd994
        105
    ryd994  
       2017-10-26 09:50:04 +08:00 via Android
    汇编能不能用?能
    写起来爽不爽?爽

    那你怎么不用汇编写个 web 应用?一定是你水平太差,学的太少,被教条束缚了。看我会用 goto,比你们不知道高到哪里去了。
    me15000
        106
    me15000  
    OP
       2017-10-26 09:52:04 +08:00
    @msg7086 秀智商下限,我没生气,只是觉得你的思想不正常
    msg7086
        107
    msg7086  
       2017-10-26 09:54:41 +08:00
    @ryd994 是的,这种「歪门邪道式」的代码,在公司里很容易滚雪球滚起来,半年一年以后当年的一句 Goto 就会变成一个代价超过一万美金的大坑。

    我们老系统里现在的各种奇葩代码,实体摘录两例。

    这是我们的 Ruby 代码……
    total_space, free_space, mount_point = `df -mh '#{storage}' | tail -1 | awk '{ print $2" "$4" "$6 }'`.split

    这是我们的 Python 代码……
    cmd = "cat /var/shares/SOME" + Id + "/SOMEFILE"
    returnCode, outLines = executeCommand(cmd)
    facetest
        108
    facetest  
       2017-10-26 09:56:34 +08:00 via Android
    @ryd994 抱歉,我第一条回复不是针对 lz 的,而是针对众多里一棍子打死 goto 的回复。
    msg7086
        109
    msg7086  
       2017-10-26 10:01:52 +08:00
    #104 @me15000
    > 你这不是明显吹嘘自己伤害别人么?
    我是头一次被这样的玻璃心震惊到了。我上一次写 VS 是我 2007 年的时候给别人写的一个开源软件,是我写着玩的。我工作是写 PHP 和 Ruby 的,手里没装 VS,代码开着 Sublime 写的。
    这也叫吹嘘?我真的高估你的水平了,是我的错,没想到一个 BFS 都能让你觉得我在吹嘘。NOIP 随便拉一个初中生都会的东西,你竟然说是吹嘘。让我打开眼界了。

    > 还强词夺理,现实中你敢这样说么?
    为什么不敢?这世界上像你这样玻璃心的人真不多,我毫不介意在别人面前这么说,如果那人也这么玻璃心,那祝他好运。

    > 你看你也太认真了
    那是,我们认真做技术认真做人,不行吗?你咬我咯。

    你想找喷那就说清楚,免得我们还说话婉转,用词还小心翼翼的。真要喷你,哪还跟你这么客气?
    ryd994
        110
    ryd994  
       2017-10-26 10:08:51 +08:00
    @msg7086 这个明显就是 bash 抄来的 Python 啊
    明显的,前任偷了个小懒

    @facetest 你要问我 goto 好不好,我只能说不好。理由和 Linus 说 C++ is horrible 的理由一样。
    因为太容易被滥用了。

    @me15000 当你拿着锤子,看什么都像钉子。当你学会 goto,你会发现什么都可以用 goto。更可怕的是这确实没错,因为到底层无非就是跳转。分支也不过是有条件的跳转。
    你知道可以这么做,不代表别人不知道。
    你能这么做,不代表你应该这么做。
    当别人不这么做的时候,你这么做了,也不代表你就比别人高明。
    me15000
        111
    me15000  
    OP
       2017-10-26 10:13:58 +08:00
    @msg7086

    别吹了,也别解释了,我也知道你这种不会服,也不懂得尊重,遇到你这种也纠缠不清,你情绪已经失控
    你最后说的那些话一般情况下,是没理的时候才能说出来的,
    又在秀自己的油条赖泼水平,把自己素质体现的淋漓尽致
    ryd994
        112
    ryd994  
       2017-10-26 10:16:23 +08:00
    @me15000 他已经很礼貌了
    毕竟没有像某人一样说“*YOU* are full of bullshit.”
    me15000
        113
    me15000  
    OP
       2017-10-26 10:17:59 +08:00
    @ryd994 我就用个 goto 跳转至于么?
    msg7086
        114
    msg7086  
       2017-10-26 10:18:35 +08:00
    @facetest 刚回去看了你原来的回帖,在此也略作回复。

    goto 也好各种高级特性也好,第一个问题是容易被不懂的人乱用,第二个问题是会对以后的软件维护性产生很大影响。

    Linux 内核也好 nginx 也好,做开发的人都是大牛,他们知道什么时候应该去用 goto,而什么时候应该正正常常去用循环来解决。特别是这只是一个尾递归,最多也就是一个 BFS,没有一丁点需要用到 goto 的地方。逻辑上该用到 goto 的,还是可以用的,我相信很多人也是要表达这样一个意思。

    包括上面 @ryd994 提到的 C++里的特性一样。一个模板一个自动指针就可以让 Debug 的人手拿 40 米大刀了(我 C++写得不多,说错见谅)自己用用无所谓,团队开发的时候就一定要小心了,要么大家都懂(比如自动指针),要么就大家都不用,或者只在局部范围内使用,避免代码污染。

    典型的例子是我们 Ruby 里用的元编程,非常强大但是又非常难以维护,所以要么团队里的人大家都搞懂这玩意,要么就避免大范围使用。
    msg7086
        115
    msg7086  
       2017-10-26 10:25:00 +08:00
    @me15000 挺好的,反正你我的对话都会永远存在于这个论坛上,那就请论坛上各位大佬看看,谁有礼貌谁没礼貌,谁有素质谁没素质呗。还我情绪失控 ww 说得像真的一样。说实话我真的不 care 你的帖子,你被封了也好你帖子被删进 chamber 了也好,对这论坛来说也就少个瘤,不痛不痒的。至于我智商有多高,那任凭你想象。至少,对吧,我不会在「分享发现」里发 goto 的帖子的。

    接下来请自便吧,我还要和帖子里其他大佬交流技术,还请不要打扰,谢谢。(/滑稽
    me15000
        116
    me15000  
    OP
       2017-10-26 10:28:59 +08:00
    @msg7086 明显你生气了么 ╮(╯▽╰)╭
    ryd994
        117
    ryd994  
       2017-10-26 10:29:02 +08:00   ❤️ 1
    @me15000 自己用不至于,你程序写的好不好我管不着。
    你贴出来也不至于,谁都有年轻的时候。写的不好很正常,谁都是这样过来的。
    这帖子我昨天就看到了,看到既然已经有那么多人在说了,也就没有添乱。留下来给后来的新手做个参考,也很好。
    但今天这贴还在,而且你完全没有听其他人的理由(不是要你听他们的结论,是理由)
    那这个帖子除了吵架,已经没有意义了,所以我建议 @Livid /go/chamber
    me15000
        118
    me15000  
    OP
       2017-10-26 10:36:41 +08:00
    @ryd994
    ╮(╯▽╰)╭ 争论本身是好事情,论坛论坛不论 不谈,还什么论坛,我不是没听进去,至少我知道,很多人不喜欢 goto,而且上面也确实有人说得一些东西 有意义的,比如尾递归
    msg7086
        119
    msg7086  
       2017-10-26 10:37:47 +08:00
    @me15000 有啥好生气的……晚饭时间的消遣娱乐而已。而且说白了,v2 的帖子发出来了就永远存在,这帖子放在这,只会给你丢脸,又不会给我丢脸,要生气的应该是你才对。
    要是我今天在论坛上发了这样的帖子,那我才要和自己生气,气自己为什么没多学点知识,这样就不会让一个楼里几十个会员轮流说了。

    这贴脱轨略远,的确可以考虑 /go/chamber 了。

    至于你本人,我从第一个回帖到现在都没有要故意说你不好或者喷你的意思,信不信随你,我不介意。
    人都是有成长阶段的,我在一个已经经历过这些的阶段,而你在一个正在经历这些的阶段,这是很正常的事情,说不定你过几年也能走到我这个位置,然后回过头来看自己以前干过的蠢事唏嘘不已。说不定过几年的我也会回头看到现在的我,觉得我自己这么宝贵的时光浪费在水帖里。但是至少现在遇到这样的贴,我还是会认真去回复的,哪怕像这样被题主喷。
    msg7086
        120
    msg7086  
       2017-10-26 10:43:13 +08:00
    最后再送你一张图,算是回应你提到我第一个回帖的回复。

    me15000
        121
    me15000  
    OP
       2017-10-26 10:46:46 +08:00
    @msg7086 ╮(╯▽╰)╭ ,行了,我筋疲力尽了,你赢了
    introom
        122
    introom  
       2017-10-26 13:14:25 +08:00 via Android
    @ryd994 你这样就没意思了,断章取义,为喷而喷。大家都有大姨夫的时候,我能理解,不过你的有点强烈哦。
    yuriko
        123
    yuriko  
       2017-10-26 13:16:40 +08:00
    用 goto 的时候,有考虑过循环展开的心情么 23333333
    SuperMild
        124
    SuperMild  
       2017-10-26 13:31:59 +08:00
    看了楼主 append,不懂 C#,但是 while(true)里面出现 if () else break 真的没问题吗?一般可以改成 do{} while()吧
    ryd994
        125
    ryd994  
       2017-10-26 13:35:20 +08:00 via Android
    @introom 呃……我只是不希望误导新人
    xomix
        126
    xomix  
       2017-10-26 15:49:25 +08:00
    @msg7086 em …………这是孙渣画的,怎么你这图不光裁图还加了自己的水印了,太过分了,你以后一定要换掉这个裁了换水印的图啊!!!
    msg7086
        127
    msg7086  
       2017-10-26 16:08:16 +08:00
    @xomix 求原图,我手里只存了这张随便网上搜的……
    xomix
        128
    xomix  
       2017-10-27 09:04:44 +08:00
    @msg7086 你可以去 lofter 上找到流亡的孙渣,账户名 孙渣 ,然后好好申请问他要,我就是有我给你这个也不对啊,别人也没 MIT 授权
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   898 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 21:28 · PVG 05:28 · LAX 13:28 · JFK 16:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.