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

简介:

本节书摘来自华章出版社《Hack与HHVM权威指南》一书中的第1章,第1节,作者 Owen Yamauchi,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

1.7.1 提炼nullable类型到non-nullable类型

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

function takes_string(string $str) {
  // ... 
}
function takes_nullable_string(?string $str) {
  if ($str !== null) {
    takes_string($str);
  }
  // ...
}

在if语句段内部,类型检查器知道$str是个非空值,所以它能够传递给函takes_string() 。注意null检查应该使用恒等操作符===和!==,而不是普通的等于操作符 (==和!=),或者转化为一个boolean类型。如果你不用恒等符号,类型检查器会报告一个错误注6。内置的函数is_null()也是可以工作的。下面是三元表达式的例子:
function takes_nullable_string(?string $str) {
takes_string($str === null ? "(null)" : $str);
// ...
}
当然你还可以使用如下的样式,即把一个分支流直接切断:

function processInfo(?string $info) {
  if ($info === null) {
    return;
  }
  takes_string($info); 
}

类型检查器知道,对函数takes_string()的调用仅仅当$info变量不为空时才会被执行。因为如果它为空,if代码段将会进入,然后函数会直接返回。(如果return语句改成throw语句,效果是一样的。)
如下是个更大的例子,展示了一个更加复杂敏感的流程控制:

function fetch_from_cache(): ?string {
  // ... 
}
function do_expensive_computation(): string {
  // ... 
}
function get_data(): string {
  $result = fetch_from_cache();
  if ($result === null) {
    $result = do_expensive_computation();
  }
  return $result; 
}

在return语句这里,类型检查器知道$result是个非空的值,所以返回类型标注就被满足了。如果if代码段进入,那么一个非空的字符串将会分配给$result。如果if代码段没有进入,那么$result必须已经是非空的字符串。
最后,Hack有个特殊内置的函数叫做invariant(),你可以使用这个函数来向类型检查器陈述事实。这个函数使用两个参数,一个是boolean的表达式,另一个是字符串类型,主要用来向读者描述问题所在 :

function processInfo(?string $info) {
  invariant($info !== null, "I know it's never null somehow");
  takes_string($info);
}

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

相关文章
ts重点学习104-对象类型得兼容性笔记
ts重点学习104-对象类型得兼容性笔记
52 0
ts重点学习110-枚举类型的兼容性笔记
ts重点学习110-枚举类型的兼容性笔记
62 0
ts重点学习110-枚举类型的兼容性笔记
ts重点学习103-对象类型得兼容性
ts重点学习103-对象类型得兼容性
54 0
ts重点学习103-对象类型得兼容性
ts重点学习109-枚举类型的兼容性
ts重点学习109-枚举类型的兼容性
64 0
ts重点学习109-枚举类型的兼容性
ts重点学习107-函数类型得兼容性知识点
ts重点学习107-函数类型得兼容性知识点
71 0
ts重点学习111-类的兼容性
ts重点学习111-类的兼容性
65 0
ts重点学习111-类的兼容性
ts重点学习112-类的兼容性笔记
ts重点学习112-类的兼容性笔记
48 0
ts重点学习32-类型断言笔记
ts重点学习32-类型断言笔记
58 0
ts重点学习113-泛型的兼容性笔记
ts重点学习113-泛型的兼容性笔记
41 0
ts重点学习112-泛型的兼容性
ts重点学习112-泛型的兼容性
52 0
ts重点学习112-泛型的兼容性