If statement 从函数提前返回是否比if语句更优雅?
我和一位同事对以下哪一项更优雅有争议。我不会说谁是谁,所以这是公正的。哪个更优雅If statement 从函数提前返回是否比if语句更优雅?,if-statement,return,If Statement,Return,我和一位同事对以下哪一项更优雅有争议。我不会说谁是谁,所以这是公正的。哪个更优雅 public function set hitZone(target:DisplayObject):void { if(_hitZone != target) { _hitZone.removeEventListener(MouseEvent.ROLL_OVER, onBtOver); _
public function set hitZone(target:DisplayObject):void
{
if(_hitZone != target)
{
_hitZone.removeEventListener(MouseEvent.ROLL_OVER, onBtOver);
_hitZone.removeEventListener(MouseEvent.ROLL_OUT, onBtOut);
_hitZone.removeEventListener(MouseEvent.MOUSE_DOWN, onBtDown);
_hitZone = target;
_hitZone.addEventListener(MouseEvent.ROLL_OVER, onBtOver, false, 0, true);
_hitZone.addEventListener(MouseEvent.ROLL_OUT, onBtOut, false, 0, true);
_hitZone.addEventListener(MouseEvent.MOUSE_DOWN, onBtDown, false, 0, true);
}
}
……或者
public function set hitZone(target:DisplayObject):void
{
if(_hitZone == target)return;
_hitZone.removeEventListener(MouseEvent.ROLL_OVER, onBtOver);
_hitZone.removeEventListener(MouseEvent.ROLL_OUT, onBtOut);
_hitZone.removeEventListener(MouseEvent.MOUSE_DOWN, onBtDown);
_hitZone = target;
_hitZone.addEventListener(MouseEvent.ROLL_OVER, onBtOver, false, 0, true);
_hitZone.addEventListener(MouseEvent.ROLL_OUT, onBtOut, false, 0, true);
_hitZone.addEventListener(MouseEvent.MOUSE_DOWN, onBtDown, false, 0, true);
}
在大多数情况下,提前返回会降低复杂性,并使代码更具可读性 这也是应用于以下领域的技术之一: 控制的最低限度使用
返回简化条件
return
,
继续
和中断
语句)Imho,是的-它的逻辑更清晰,因为返回是显式的,并且正好位于条件旁边,并且可以很好地用类似的结构进行分组。这在“return”替换为“throw new Exception”时更为适用。选项2可读性更强,但当可能需要添加else时,代码的可管理性会失败
因此,如果您确定,没有其他方法可以选择选项2,但是如果可以选择else条件,那么我更喜欢选项1,只要早期返回在函数/方法体的顶部组织为块,那么我认为它们比添加另一层嵌套更具可读性 我尽量避免身体中部的早期返回。有时它们是最好的方法,但大多数时候我认为它们会使事情复杂化
此外,作为一般规则,我尝试最小化嵌套控制结构。很明显,这一点你做得太过分了,所以你必须谨慎行事。对我来说,将嵌套的if转换为单个开关/大小写要清楚得多,即使谓词重复了一些子表达式(假设这不是一个性能关键的循环,因为语言太笨,无法消除子表达式)。特别是我不喜欢在长函数/方法体中组合嵌套的ifs,因为如果出于某种原因跳入代码的中间,您最终会上下滚动以在心里重建给定行的上下文。选项1更好,因为您在过程中应该有最少数量的返回点。 也有类似的例外 if (a) { return x; } return y; 如果(a){ 返回x; } 返回y;
由于语言的工作方式,但一般来说,最好尽可能少的退出点。如前所述,提前返回更具可读性,特别是如果函数体很长,您可能会发现在3页函数中错误地删除}(其本身不是很优雅)试图编译它可能需要几分钟的非自动调试 它还使代码更具声明性,因为这是您向另一个人描述代码的方式,因此开发人员可能离一个人很近,能够理解它
如果以后函数的复杂度增加了,并且你有了很好的测试,你可以简单地将每个选项包装在一个新函数中,并在case分支中调用它们,这样你就可以保持声明式风格。根据我的经验,在项目中使用早期返回的问题是,如果项目中的其他人不习惯它们,他们不会去找他们的。因此,无论是否提前返回,如果涉及多个程序员,请确保每个人至少都知道他们的存在 我个人编写代码以尽快返回,因为延迟返回通常会带来额外的复杂性,例如试图安全地退出一系列嵌套循环和条件
因此,当我查看一个不熟悉的函数时,我要做的第一件事就是查找所有的
返回值。真正有帮助的是设置语法着色,使return
的颜色与其他颜色不同。(我选择红色。)这样一来,返回就成为了确定函数功能的有用工具,而不是为粗心的人隐藏的绊脚石。我更喜欢避免在函数开始时立即返回,并尽可能在调用方法之前放入限定逻辑,以防止进入方法。当然,这取决于方法的用途
但是,如果方法简短可读,我不介意返回到方法的中间。在我看来,如果这个方法很大,它的可读性就不是很强,所以它要么被重构成多个函数,并带有内联返回,要么我将在最后以一个返回显式地从控制结构中分离出来。这是一种可以打破规则的情况(即最佳实践)。通常,您希望函数中的返回点尽可能少。这样做的实际原因是它简化了您对代码的阅读,因为您可以始终假设每个函数都将接受其参数、执行其逻辑并返回其结果。为各种情况输入额外的返回往往会使逻辑复杂化,并增加读取和完全搜索代码所需的时间。一旦代码进入维护阶段,当新程序员试图破译逻辑时,多次返回可能会对他们的生产力产生巨大影响(特别是
public function setHitZone(target:DisplayObject):void
{
if(_hitZone != target)
setHitZoneUnconditionally(target);
}
public function setHitZoneUnconditionally(target:DisplayObject):void
{
_hitZone.removeEventListener(MouseEvent.ROLL_OVER, onBtOver);
_hitZone.removeEventListener(MouseEvent.ROLL_OUT, onBtOut);
_hitZone.removeEventListener(MouseEvent.MOUSE_DOWN, onBtDown);
_hitZone = target;
_hitZone.addEventListener(MouseEvent.ROLL_OVER, onBtOver, false, 0, true);
_hitZone.addEventListener(MouseEvent.ROLL_OUT, onBtOut, false, 0, true);
_hitZone.addEventListener(MouseEvent.MOUSE_DOWN, onBtDown, false, 0, true);
}