在Java中使用'return'来终止for循环是否是一种不好的编程风格?

15

我正在为计算机科学课程做一个基本的Java项目,这个项目有一个嵌套在while循环内的for循环。

不允许使用break来提前结束for循环。我发现return似乎具有与break相同的效果。使用return作为中断循环的方法是否是不好的风格?

我的for循环必须检查三个不同的语句,但如果它发现其中一个为true,则应立即结束而不继续检查其余语句。

我尝试在while循环中加入一个布尔运算符来控制for循环,但这并不能控制for循环中的操作,直到for循环到达结尾。

此外,如果return没有返回任何内容,是否会有影响?

299/01/11更新:非常感谢大家的评论。阅读所有讨论对我很有帮助。

我与我的导师交谈后发现,为了获得满分,我也不应该使用return

所以我发现在for循环中设置一个布尔值的建议非常有用,因为我不知道可以这样做。


2
我想知道不允许使用“break”的复杂推理背后的原因。 - andri
1
@andri,既然这是一个基本的Java类,我完全明白(并同意)为什么禁止使用break。如果不这样做,那么答案有一半将只是带有break语句的可怕while(true)循环... - Michael Berry
3
展示如何不使用以及何时使用可能更好,而不是禁止它。禁止 break 让整个班级的学生产生了“ break 是不好的风格”的印象。 - Jonathon Faust
1
在理想的情况下,是的,@Jonathon。但实际上,在教育领域中,你只能涵盖一定数量的内容,否则事情会变得混乱,而不使用break这个通用规则会消除这种混乱因素。稍后再回顾它并举出何时何地使用它是合适的,这没有问题,但如果学生们第一次学习如何使用循环,那么这是一个相对高级的话题! - Michael Berry
@berry120听起来当你第一次使用某个东西并且需要使用这个东西的一个特性而被任意限制时会更加困惑...他正在这里询问如何不使用正确的工具完成任务。在一门早期计算机科学课程中,我认为让它工作是最重要的事情。在以后的课程中,你可以担心代码的质量。 - grinch
显示剩余4条评论
11个回答

17

如果循环后的第一件事是一个return语句,那么它们只有在等价。

无论如何,如果你的讲师不允许使用break,他们可能也不允许使用return

你应该知道这些规则背后有很好的基础(防止代码混乱,使编写可维护的代码更容易),但有时会被过度执行。

例如,下面这段代码片段没有任何难懂之处:

if (x == 0)
    return 0;
return x - 1;

即使它有多个return语句,也可以实现目标。
所谓的“不允许多个return”的做法应该是这样的:
int y = x - 1;
if (x == 0)
    y = 0;
return y;

在我看来,使用这种方式既不易读,也浪费了空间。

当你遇到非常复杂的逻辑时,人们为了避免使用break和/或return而跳过的步骤会导致条件语句变得难以阅读。

听取你的讲师的建议 - 毕竟他们掌握着你的成绩。然后,一旦进入实际工作领域,你可以从教条主义转向实用主义,并自行决定。

请参阅此处以获取有关这些问题在教育机构以外的一些好建议。


+1 很好的解释,尽管我认为在学校(开始学习时)强制执行这些规则可能会有所帮助。也就是说,当人们还不能明智地使用某些工具时,最好不要使用它。 (我在谈论一个“break”:我看不出你如何“过度使用”“return”) - Nikita Rybak
不能明智地使用工具是经验不足的结果。你在学校提交的代码除了自己的学习之外没有任何用处,所以你最好尽可能多地使用和滥用许多功能,从而第一手发现什么是一个坏主意。支持指导,反对教条主义! - E.M.
问题也可以在语言层面上解决。例如,人们喜欢对缩进(4个或8个空格,无论哪种)和大括号的位置(放在新行还是不放)“务实”,然后像Google的“Go”语言背后的设计师一样,提出了强制缩进和大括号位置在语言规范中。不再争论,不再有“教条主义与实用主义”的问题。它已在规范中定义。一个语言可能会规定只有一个返回语句,那么,“教条主义与实用主义”就不复存在了 :) - Gugussee
@Whisty 很遗憾,“让我们编写最糟糕的代码”这种方法很少在教学中得到回报。而且初学者很少能够看出好代码和坏代码之间的区别。你无法想象向13岁的孩子解释一致缩进的好处有多难。唯一的方法就是强制执行它。然后,在几周/几个月之后,他们会看到好处。这适用于大多数学习领域,不仅仅是编程。 - Nikita Rybak
1
@Nikita,我理解你的观点。我想我不同意的是“当人们不能明智地使用某个工具时,最好不要使用它”的措辞。我必须使用它才能学会如何明智地使用它。 - E.M.
@E.M. 我同意。一旦13岁的孩子不得不回去阅读他们写了一段时间的非常糟糕、缩进不一致的代码,他们就真正学到了这个教训。我认为当你亲眼看到这些教训时,它们会更加深刻,并且更有意义。在学校里,还有什么比犯错误并从中学习更好的地方呢? - grinch

7
首先,如果你使用得当,使用break并不是一种不好的风格。虽然我理解为什么你的教授现在坚持不使用break(因为很多人,特别是初学者,往往会“滥用”它),但没有理由完全禁止它。
使用return作为中断循环的方法是否是一种不好的风格?个人认为,这样做没问题:代码只会变得更简单。但显然,你的教授在这里拥有更高的权威。整个问题非常主观,因此我无法代表他发表意见。
但是,无论你的教授怎么说,使用return在循环中并不是一种不好的风格。

5
这个问题似乎涉及到一个非常古老但仍未解决的争论,即“单一方法退出点 vs. 多个方法退出点”。
因此,如果在循环中使用 return 使您(或您的老师)感到担忧,您(或他)可以看看这里
回答您的问题。在我(以及不仅仅是我)的观点中,在循环中使用 return 绝对没有问题。
请注意,过度使用可能会降低代码可读性(有关详细信息/示例,请参见链接的答案)。

很遗憾,这个链接已经失效了。 - PPartisan

3
这取决于您的方法返回类型。如果返回类型是void,则返回语句必须为空:此外,“return”不返回任何内容是否重要?
return;

否则,返回语句必须返回所需的类型,例如:
return true; // legal for boolean return type
return null; // legal for all object types
return "Hello"; // legal if return type is String

3
这是关于完美代码的内容。
for(int i; i < stop; i++) {
 boolean flag = true;

 while(flag && condition) {
  //some action 
  if(shouldIstop) {
     flag = false;
  }
 }
}

当你将标志设置为false时,你将退出while循环,当你将i设置为stop时,你也将退出for循环。


3

从纯粹的观点来看,break有争议的用法。while循环的重点在于使用循环开始时的条件来跳出它,如果你开始在循环中涌入break语句而不是正确地获取条件(这是一个快速的技巧,学生们可能会被诱惑去使用,如果他们无法找到正确的方法!)同样适用于continue和在循环中间返回。

所有这些语言特性都是有原因的,是的,有时它们是做事情的最好方式。然而,当刚刚开始编程时,你正确而明智地使用它们的机会很少,它们更可能被用作免费的“黑客卡片”来让我脱离困境,而不必理解这个东西是如何工作的。我认为,这是禁止在基础编程课程中使用它们的足够好的理由。


2
您可以像这样提前终止for循环。
for (int i = 0; i < SOMELIMIT && (!found); ++i) {...}

2

我想你的导师希望你在for循环的条件部分使用break语句。你需要在循环之前声明这个条件,并在循环内部改变它。

boolean stop = false;

for (...; ... && !stop; ...) {
    ...
    if (...) {
        stop = true;
    }
}

2
breakreturn 不是一样的。 break 会停止内部循环的执行,return 会从当前方法中返回 - 也就是说,在方法中不会再执行任何其他操作。据我所知,在循环中使用 break 没有任何问题; 假设这是一个人为的要求,为了让你想到替代逻辑。使用 return 也没有问题; 这将使你避免可怕的嵌套条件语句 (if 子句)。

2
如果您不被允许使用break,那么不使用return也是有道理的,因为每个带有break的循环都可以重写为一个带有return的循环(通过将其外包到单独的函数中)。
从非作业角度来看,break(和return)是非常有用的语言特性,通常不被认为是不好的风格(当然,每个语言结构都可以被滥用以编写糟糕的代码)。
然而,在作业场景下,我想仅仅通过使用return来“解决”缺少break的问题会失去作业的意义。您应该考虑其他方法来解决您的任务。
“我尝试在控制for循环的while循环中放置布尔运算符,但这并不能控制for循环内部发生的事情,直到for循环到达结尾。”
这是真的,但是,通过使用if语句,您还可以根据布尔值执行/不执行循环内部的代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接