假设我有静态连接器,它允许代理不同适配器的实例:
$m = Connector::take('mcrouter');
$db = Connector::take('production_database');连接器必须在运行时插入和处理连接:
protected $connection;
abstract protected function openConnection($config);适配器中的某个地方:
$this->connection = $this->openConnection($config);连接是一个对象,可以是Memcached、MySQLi等的实例,也可以是NULL。所以,从逻辑上讲,我想这样做:
protected ?object $connection;
abstract protected function openConnection($config):?object;但同时,连接并不是"object“的真正实例,它是Memcached的实例,结果是:
可捕获的致命错误:黑客类型错误:无效赋值
在这种情况下,唯一可行的解决方案是根本不定义类型。有什么诀窍来定义宇宙对象吗?
发布于 2015-08-15 15:19:36
Hack中的通用类型是当您省略类型注释时得到的;它与所有内容都兼容。object不是打字机所知道的类型,因此它假设您在某个地方有一个class object。
连接是一个对象,可以是Memcached、MySQLi等的实例,也可以是NULL。
正确的方法是定义这两个对象都实现的接口,并在这里使用该接口作为类型。
拥有一个通用对象类型不会向打字机提供任何信息;它仍然不知道调用该对象的哪些方法是有效的。接口为打字机提供了该信息。
请注意,“什么方法在什么时候调用是安全的”是在您的应用程序中隐式编码的东西--代码通过一些外部方法知道什么时候调用Memcached、MySQLi等方法是安全的,否则您的代码就无法工作!Hack的类型系统,以及一般的类型系统,只是强迫您将其显式化。
顺便说一句,您确实不应该从HHVM获得类型错误,因为这是一种最后的检查。尝试直接运行hh_client检查器,甚至在IDE中显示其结果;它将给您提供比HHVM提供的更快的迭代周期和更多的信息。
https://stackoverflow.com/questions/32023839
复制相似问题