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);

        }

在大多数情况下,提前返回会降低复杂性,并使代码更具可读性

这也是应用于以下领域的技术之一:

控制的最低限度使用

  • 通过使用专门的 构建这样的国际化,, 继承,以及类等类 默认值、一次类和一次类 分离器
  • 使用早期
    返回简化条件
  • 通过使用action applicator最小化循环构造的使用 类,例如类分离和 类FileSystemVisitor
  • 通过提前退出简化迭代逻辑(通过
    return
    继续
    中断
    语句)
  • 在您的示例中,我会选择选项2,因为它使代码更具可读性。我在检查函数参数时使用相同的技术。

    在这种情况下(一个测试,没有其他子句),我喜欢测试并返回。它清楚地表明,在这种情况下,无需阅读函数的其余部分,就无需执行任何操作

    然而,这是分裂最好的头发。我相信你一定有更大的问题要担心:)啊,卫报


    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);
    
        }