天天看点

《Hack与HHVM权威指南》——1.7.1 提炼nullable类型到non-nullable类型

null检查语句在从空值(nullable)的类型到非空值(non-nullable)类型的转变中经常用到。下面是个通过了类型检查器检查的示例。

在if语句段内部,类型检查器知道$str是个非空值,所以它能够传递给函takes_string() 。注意null检查应该使用恒等操作符===和!==,而不是普通的等于操作符 (==和!=),或者转化为一个boolean类型。如果你不用恒等符号,类型检查器会报告一个错误注6。内置的函数is_null()也是可以工作的。下面是三元表达式的例子:

function takes_nullable_string(?string $str) {

takes_string($str === null ? "(null)" : $str);

// ...

}

当然你还可以使用如下的样式,即把一个分支流直接切断:

类型检查器知道,对函数takes_string()的调用仅仅当$info变量不为空时才会被执行。因为如果它为空,if代码段将会进入,然后函数会直接返回。(如果return语句改成throw语句,效果是一样的。)

如下是个更大的例子,展示了一个更加复杂敏感的流程控制:

在return语句这里,类型检查器知道$result是个非空的值,所以返回类型标注就被满足了。如果if代码段进入,那么一个非空的字符串将会分配给$result。如果if代码段没有进入,那么$result必须已经是非空的字符串。

最后,hack有个特殊内置的函数叫做invariant(),你可以使用这个函数来向类型检查器陈述事实。这个函数使用两个参数,一个是boolean的表达式,另一个是字符串类型,主要用来向读者描述问题所在 :

在运行环境中,如果invariant()的第一个参数值被证明是false,那么一个不变异常(invariantexception)将会触发。类型检查器知道这并且推断出:在invariant()函数后面的调用中,$info不会是个空值。否则的话,一个异常早就被抛出了,而代码根本就不会执行到这个地方。