私は PHP プロジェクトを Hack に変換する過程にあり、ちょっとした障害に遭遇しました。私がやろうとしているのは、IoC コンテナーを PHP から Hack に書き直すことです。すべてを Hack タイプ チェッカー ツールに渡すのに少し苦労しています。
つまり、基本的に私が持っているのは、文字列をクロージャ マッピングに登録できるコンテナです。アイデアは、クロージャーにクラスをインスタンス化するロジックが含まれているということです。コンテナーは、作成したインスタンスも格納し、新しいインスタンスを強制的に作成することもできます。ここに私のコンテナコードがあります:
<?hh // strict
class Container {
private Map<string, mixed> $instances = Map {};
private Map<string, (function (Container): mixed)> $registered = Map {};
public function register(string $alias, (function (Container): mixed) $closure): void
{
$this->registered[$alias] = $closure;
}
public function get(string $alias): ?mixed
{
if (!$this->registered->contains($alias)) {
return null;
}
$instance = $this->instances->get($alias);
if ($instance !== null) {
return $instance;
}
$closure = $this->registered->get($alias);
if ($closure !== null) {
$this->instances->set($alias, $closure($this));
}
return $this->instances->get($alias);
}
public function getNew(string $alias): ?mixed
{
if (!$this->registered->contains($alias)) {
return null;
}
$closure = $this->registered->get($alias);
return ($closure !== null) ? $closure($this) : null;
}
}
このクラス自体は型チェッカーに合格しているようですが、Container::get()
orを使用するContainer::getNew()
と、戻り値が typemixed
であるため、これらによって返されたオブジェクトに対してメソッドを実行しようとすると、このエラーがスローされます。
メンバー x にアクセスしようとしていますが、これはオブジェクトではなく、混合値です
混合では明らかに非オブジェクトが許可されるため、これが理にかなっていることがわかりました。そのため、そのようなコードを でラップする必要がありますが、これをis_object()
行っても型チェッカーのエラーが抑制されないようです。タイプチェッカーが理解できる、何かがHackのオブジェクトであることを確認するより良い方法はありますか?
また、この IoC コンテナー クラスは混合型に大きく依存しているため、私には少し見苦しいです。実行時に戻り値がオブジェクトであることを確認する必要があるのも理想的ではありません。これを行うより良い方法はありますか?ミックスをインターフェイス(IContainableなど)に変更するというアイデアを試してみて、コンテナに格納したいクラスにこれを実装させましたが、タイプチェッカーは、IContainableインターフェイスにメソッドが含まれていないと不平を言いましたコンテナから返されたオブジェクトを呼び出そうとしていました(コードの同じポイントでエラーが発生しましたが、別の理由で)。おそらく、私はこのアプローチで成功に近かったのでしょうか?
助けてくれてありがとう。