今天我有一个同事建议我重构我的代码,使用label语句来控制我创建的2个嵌套for循环的流量.我以前从未使用它们,因为我个人认为它们会降低程序的可读性.如果论证足够坚实,我愿意改变主意使用它们.人们对标签声明的看法是什么?
如果您可以跳过两个循环(或包含switch语句的循环),则可以更轻松地表达许多算法.不要为此感到难过.另一方面,它可能表明过于复杂的解决方案.所以退后一步看看问题.
有些人更喜欢所有循环的"单入口,单出口"方法.也就是说完全避免中断(并继续)和早期返回循环.这可能会导致一些重复的代码.
我强烈要避免做的是引入辅助变量.隐藏在州内的控制流动增加了混乱.
将标记的循环分成两种方法可能很困难.例外情况可能太重了.尝试单入口,单退出方法.
标签就像goto一样:谨慎使用它们,只有当它们使代码更快,更重要的是,更容易理解,
例如,如果你处于六级深度的大循环中并且遇到一个条件使得循环的其余部分无意义地完成,那么在条件语句中有6个额外的陷阱门以提前退出循环是没有意义的.
标签(和goto的)并不是邪恶的,只是有时人们以不好的方式使用它们.大多数时候我们实际上都在尝试编写代码,因此对于您和下一个程序员来说这是可以理解的.快速超速是一个次要问题(警惕过早优化).
当Labels(和goto)被滥用时,它们会使代码的可读性降低,这会让您和下一位开发人员感到悲伤.编译器不关心.
您很少需要标签,因为它们很少使用,所以很容易混淆.但是,如果您需要使用一个,请使用一个.
BTW:这个编译并运行.
class MyFirstJavaProg { public static void main(String args[]) { http://www.javacoffeebreak.com/java101/java101.html System.out.println("Hello World!"); } }
我很想知道你对标签的替代品是什么.我认为这几乎可以归结为"尽早返回"与"使用变量来保持返回值,最后只返回"的论点.
当您有嵌套循环时,标签是非常标准的.他们真正降低可读性的唯一方法是,其他开发人员以前从未见过它们并且不理解它们的含义.
我从来没有在Java代码中看到过"野外"使用过的标签.如果你真的想要突破嵌套循环,看看你是否可以重构你的方法,以便早期的return语句能够达到你想要的效果.
从技术上讲,我猜早期退货和标签之间没有太大区别.但实际上,几乎每个Java开发人员都看到了早期的回报,并知道它的作用.我猜许多开发人员至少会对标签感到惊讶,可能会感到困惑.
我在学校教过单入/单出正统,但我已经开始欣赏早期的返回语句和断开循环,以简化代码并使其更清晰.
我认为通过新的for-each循环,标签可以非常清晰.
例如:
sentence: for(Sentence sentence: paragraph) { for(String word: sentence) { // do something if(isDone()) { continue sentence; } } }
我认为通过让你的标签与新的for-each中的变量相同,我看起来非常清楚.事实上,也许Java应该是邪恶的,并为每个变量添加隐式标签
我在某些地方支持它们,我发现它们在这个例子中特别有用:
nextItem: for(CartItem item : user.getCart()) { nextCondition : for(PurchaseCondition cond : item.getConditions()) { if(!cond.check()) continue nextItem; else continue nextCondition; } purchasedItems.add(item); }
我使用Java标记的循环来实现Sieve方法来查找素数(为项目Euler数学问题之一完成),这使得它比嵌套循环快10倍.例如,如果(某些条件)返回外循环.
private static void testByFactoring() { primes: for (int ctr = 0; ctr < m_toFactor.length; ctr++) { int toTest = m_toFactor[ctr]; for (int ctr2 = 0; ctr2 < m_divisors.length; ctr2++) { // max (int) Math.sqrt(m_numberToTest) + 1 iterations if (toTest != m_divisors[ctr2] && toTest % m_divisors[ctr2] == 0) { continue primes; } } // end of the divisor loop } // end of primes loop } // method
我问过C++程序员标签循环有多糟糕,他说他会谨慎使用它们,但它们偶尔会派上用场.例如,如果您有3个嵌套循环,并且对于某些条件,您希望返回到最外层循环.
所以他们有自己的用途,这取决于你试图解决的问题.