【问题标题】:Is it acceptable to return in middle of class __construct()在类中返回是否可以接受 __construct()
【发布时间】:2012-10-03 18:28:23
【问题描述】:

我知道有很多与此相关的问题。但是,我没有设法找到简单问题的答案(我不是在询问从构造函数返回值的问题,我认为我理解构造函数应该返回什么)。

有什么理由避免在__construct 中使用return

或者这种完全可以接受的编码风格在未来不会因为return而中断:

class A {
    protected $tristate = null;
    function __construct() {
        // Constructor returns instance of class automatically
        // no need to `return $this`
    }
    protected function Logic() {
        return rand(0, 1) === 1;
    }
}

class B extends A {
    function __construct() {
        parent::__construct();
        if ($this->Logic()) return;
        $this->tristate = true;
    }
}

上面的一个已经过测试并且它按预期工作(在我的开发环境中),它将父 $tristate var 50/50 设置为 NULL/TRUE,但它会在未来工作吗?使用void return 在构造函数中间返回时出现的任何问题。

我想到的另一件事是我应该使用return $this 而不是普通的return,这通常是无效的,但PHP 似乎无论如何都会返回实例,答案很可能是return $this 和普通的return 都只是一样好。

【问题讨论】:

  • 这个类只是一个简化的例子,因为我的问题不是关于从其构造函数返回除普通类实例之外的东西(任何特殊的)。我在构造函数中间询问 returnìng 以及在构造函数中间返回 void(似乎被 PHP 引擎替换)可能出现的问题。

标签: php oop constructor


【解决方案1】:

这没有任何后果,我认为永远不会有。您可以随时从构造函数返回任何内容。返回值(如果有)将被忽略。

【讨论】:

  • 事实上我不能返回几乎任何东西,因为构造函数应该总是返回对象或者在失败的情况下抛出错误/(返回null?)。但是,嘿,你已经说过了,我只是重复一遍。
  • 我不是这么说的。什么时候回来都没有关系。
  • 知道了。我正在考虑真正从盒子外面得到一些东西......所以今天忽略了返回值,是否有任何理由可以让我们等待 __constructor 可以真正返回其他东西,例如快速错误处理,如if (!$obj=new MyClass()) die('error');
  • 我无法想象这会改变。它会破坏向后兼容性非常糟糕。
【解决方案2】:

来自doc

构造函数 void __construct ([ 混合 $args [, $... ]] )

来自pseudo type definition

void 作为返回类型意味着返回值是无用的。

所以你可以返回任何东西......但它是useless。在您的情况下,return 适用于退出函数执行:它只是允许的。

另一个问题是这是一个好习惯还是坏习惯......

我认为简单的return ; 是节省一些 IF 语句和烦人的缩进的好习惯。 有值的返回(即return false;),如果没用,是不好的做法,因为没有意义。

【讨论】:

    【解决方案3】:

    确保no 方法returns 早点是一个很好的经验法则——除此之外,这意味着在 6 个月的时间里,当你回到那个 1500 行函数时你知道你真的不应该写,但无论如何都写了,你有一个稍微不那么噩梦的时间来理解这个愚蠢的东西是如何工作的:)

    通过使用否定逻辑检查 - if ( ! $this->Logic() ) 您可以获得与提前返回相同的效果,但是您现在可以返回代码,知道它永远不会在中间的某个地方随机退出您的方法。

    当然,除了那个小声音说“我知道我不应该”之外,没有什么能阻止你这样做,但是还有另一个声音说“哦,继续,会没事的,你会记住的!”。不要听第二个声音,正确地去做:P


    要明确的快速更新 - 没有技术原因可以避免在构造函数中使用 returning(new 关键字强制它返回对象,并覆盖构造函数返回的内容),有一个很好的 合乎逻辑的理由不这样做。

    【讨论】:

    • “在 6 个月的时间里,当你回到那个 1500 行的函数时,你知道你不应该真的写,但还是写了”——伙计,别想我了。跨度>
    • 很多人觉得提前退出其实是保持代码干净的一种聪明方式。它倾向于减少不必要的嵌套。这也是我的看法。不想争论,但我确实认为这是一个相当主观的意见。
    • 如果你写了一个 1500 行的函数/方法,你应该羞愧地垂头丧气。它应该正好适合页面/屏幕。如果没有,请稍微打破它。您应该能够在屏幕上看到函数/方法的顶部和底部。这大约是(最多)100 行代码。 **这是礼貌的关于函数中的 1500 行代码**
    • “确保没有方法提前返回是一个很好的经验法则” 为什么?所以我们可以有一个不计其数的布尔值和/或嵌套的 if 来混淆我们实际尝试做的事情?听起来不错。
    • @Ed 和 NullUserException,可以这么说,我同意你的观点(从答案中应该很明显)。在实践中,即使是因为你继承了它,你也会看到它发生。在工作中,我们有许多 10k+ 行文件,以及一些 2k+ 行函数。是的,这很糟糕,但是说“上帝太糟糕了”并没有帮助。当他们回到那些线路的某个地方时,祝你好运。使用大括号,您每次都可以站起来查看它正在运行的检查。在一个理想的世界里,当然,去吧 - 当你找到一个理想的世界时请告诉我,我对它很感兴趣
    猜你喜欢
    • 2019-08-21
    • 1970-01-01
    • 1970-01-01
    • 2014-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-06
    相关资源
    最近更新 更多