HackLang类型为不同的对象

时间:2015-08-15 10:31:06

标签: hacklang

假设我有静态连接器,允许代理不同适配器的实例:

$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;

但同时连接并不是“对象”的实例,例如它是Memcached的实例,结果是:

  

可捕获的致命错误:黑客类型错误:无效的分配

在这种情况下唯一的解决方案是根本不定义类型。 是否有一些定义通用对象的技巧?

1 个答案:

答案 0 :(得分:1)

Hack中的通用类型是省略类型注释时获得的类型;它与一切兼容。 object不是类型检查器已知的类型,因此假定您在某处有class object

  

连接是一个对象,可以是Memcached,MySQLi等的实例,也可以是NULL。

正确的方法是定义这两个对象实现的接口,并将该接口用作此处的类型。

拥有通用对象类型不会向类型检查器提供任何信息;它仍然不知道调用该对象的有效方法。界面为类型检查器提供了信息。

请注意“在您的应用程序中隐式编写的”可以安全调用的方法 - 代码通过某些外部方式知道何时可以安全地调用Memcached,MySQLi等的某些方法,否则您的代码将无法使用工作! Hack的类型系统和一般的类型系统只会迫使你明确这一点。

顺便说一句,你真的不应该把你的类型错误当作来自HHVM的可捕获的致命错误;这是最后的手段。尝试直接运行hh_client检查程序,甚至可以在IDE中显示其结果;它将为您提供更快的迭代周期,以及比HHVM提供的更多信息。