如何在没有 Nullable 的情况下实现单例模式

How to Implement Singleton Pattern without Nullable

我正在尝试在 Hack 中实现单例模式。但是,我一直 运行 关注 Nullable 的问题。

<?hh //strict

class Foo {
    private static Foo $foo;

    public function __construct() {
        // Do stuff here.
    }        

    public static function theFoo(): Foo {
        if (null === self::$foo) {
            self::$foo = new Foo();
        }

        return self::$foo;
    }
}

$aFoo = Foo::theFoo();

执行时出现错误:

Catchable fatal error: Hack type error: Please assign a value at foo.hh line 4

类型检查器 returns 也有类似的:

foo.hh:4:24,27: Please assign a value (Typing[4055])

如何为静态 属性 分配默认值?

How do I assign a default value to a static property?

如果它是一个对象,就像在这种情况下,你不能。使用原语,你可以做这样的事情:

<?hh // strict

class Foo {
  private static int $x = 0;
  // ...
}

但是,对于对象,您需要说 private static Foo $x = new Foo() 这是不允许的 - 您不能像那样初始化静态变量,因为它必须调用构造函数,其中涉及 运行 代码,而 PHP 没有初始化顺序和 运行 代码的概念(其他语言,尤其是 C++,有)。没有深层的技术原因我们不能有这样的概念,它现在不是语言的一部分。

正确的做法是使静态 nullable。实际上,当您执行 if (null === self::$foo) 时,您实际上已经隐含地对待它了——正如所写的那样,self::$foo 实际上不能为空,因为您没有给它一个可为空的类型,因此检查什么都不做。你可能想做的是:

<?hh // strict

class Foo {
  private static ?Foo $foo;
  // ...
}