不同对象的 HackLang 类型
HackLang type for different objects
假设我有允许代理不同适配器实例的静态连接器:
$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;
但同时connection并不是"object"的实例,而是Memcached的实例,结果是:
Catchable fatal error: Hack type error: Invalid assignment
在这种情况下唯一可行的解决方案是根本不定义类型。
通用对象的定义有什么技巧吗?
Hack 中的通用类型是您省略类型注释时得到的;它与一切兼容。 object
不是类型检查器已知的类型,因此它假定您在某处有一个 class object
。
The connection is an object and could be an instance of Memcached, MySQLi etc. or NULL.
执行此操作的正确方法是定义一个由这两个对象实现的接口,并将该接口用作此处的类型。
拥有通用对象类型不会向类型检查器提供任何信息;它仍然不知道在该对象上调用哪些方法是有效的。该接口为类型检查器提供了该信息。
请注意,"what methods are safe to call when" 是在您的应用程序中隐式编码的东西——代码通过一些外部方式知道何时可以安全地为 Memcached、MySQLi 等调用某些方法,否则您的代码将无法工作! Hack 的类型系统,以及一般的类型系统,只是强制你明确这一点。
顺便说一句,你真的不应该把你的类型错误当作来自 HHVM 的致命错误;这是不得已的检查。直接尝试 运行 hh_client
检查器,甚至可能在您的 IDE 中显示其结果;它将为您提供更快的迭代周期,以及比 HHVM 提供的更多信息。
假设我有允许代理不同适配器实例的静态连接器:
$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;
但同时connection并不是"object"的实例,而是Memcached的实例,结果是:
Catchable fatal error: Hack type error: Invalid assignment
在这种情况下唯一可行的解决方案是根本不定义类型。 通用对象的定义有什么技巧吗?
Hack 中的通用类型是您省略类型注释时得到的;它与一切兼容。 object
不是类型检查器已知的类型,因此它假定您在某处有一个 class object
。
The connection is an object and could be an instance of Memcached, MySQLi etc. or NULL.
执行此操作的正确方法是定义一个由这两个对象实现的接口,并将该接口用作此处的类型。
拥有通用对象类型不会向类型检查器提供任何信息;它仍然不知道在该对象上调用哪些方法是有效的。该接口为类型检查器提供了该信息。
请注意,"what methods are safe to call when" 是在您的应用程序中隐式编码的东西——代码通过一些外部方式知道何时可以安全地为 Memcached、MySQLi 等调用某些方法,否则您的代码将无法工作! Hack 的类型系统,以及一般的类型系统,只是强制你明确这一点。
顺便说一句,你真的不应该把你的类型错误当作来自 HHVM 的致命错误;这是不得已的检查。直接尝试 运行 hh_client
检查器,甚至可能在您的 IDE 中显示其结果;它将为您提供更快的迭代周期,以及比 HHVM 提供的更多信息。