我正在将PHP项目转换为Hack,我遇到了一些障碍.我想要做的是将一个IoC容器从PHP重写为Hack,并且我在通过Hack类型检查工具获取所有内容时遇到了一些麻烦.
基本上我所拥有的是一个容器,它允许您将字符串注册到闭包映射.想法是闭包包含实例化类的逻辑.容器还存储它创建的实例,还允许您强制创建新实例.这是我的容器代码:
$instances = Map {}; private Map$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()
或者Container::getNew()
,因为返回是类型时mixed
,当我尝试对这些返回的对象执行方法时,它会抛出此错误:
您正在尝试访问成员x,但这不是对象,它是一个混合值
现在我知道这是有道理的,因为混合显然允许非对象,所以我必须确保将这些代码包装在一个is_object()
,但是这样做似乎并没有抑制类型检查器中的错误.有没有更好的方法来确认某些东西是Hack中的对象,类型检查器会理解?
此外,这个IoC容器类在很大程度上依赖于混合类型,这对我来说有点难看.在运行时也必须确保其返回是对象并不理想.有没有更好的方法可以做到这一点?我确实尝试过将混合更改为接口(如IContainable或其他东西)的想法,并且我想在容器中存储任何类实现这个,但是类型检查器抱怨IContainable接口不包含该方法我试图调用从容器返回的对象(所以代码中的同一点出错,但原因不同).也许我接近这种方法的成功?
谢谢你的帮助.