《Hack与HHVM权威指南》——2.5 重温未决的类型

简介:

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

2.5 重温未决的类型

在引导范例中,我们看到了当你使用类型检查器的时候,它们能够推断泛型类的类型实参。这里,类型检查器知晓,对于类型形参Tval,Wrapper已经用int类型替代进行实例化了。
$w = new Wrapper(20);
这个推断算法的准确细节已经超出了这里的讨论范围,但是这里仍然有一些需要知晓的结论。
类型检查器应该接受下面的代码吗?

function takes_wrapper_of_int(Wrapper<int> $w): void {
  // ...
}

function main(int $n): void {
  $wrapper = new Wrapper($n);
  takes_wrapper_of_int($wrapper);
}

直觉上来说,它应该是被接受的,事实也是这样。类型检查器知道在main()函数的最后一行,变量$wrapper是一个整型的wrapper,所以允许这个调用。
那么,换成下面的代码呢?

function main(string $str): void {
  $wrapper = new Wrapper($str);
  takes_wrapper_of_int($wrapper);
}

看起来这应该不允许执行,事实也确实如此。
那么,如果我们再换成如下的代码呢?

function main(int $n, string $str): void {
  $w = new Wrapper($n);
  $w->setValue($str);
}

正如我们在第一个例子中看到的一样,类型检查器似乎明白$wrapper在第一行后面是个Wrapper。所以看起来类型检查器应该报告一个错误:在Wrapper上,你不应该对setValue()传递一个字符串作为实参。但是事实上,这段代码是合法的。
这就是类型检查器使用未决的类型的另外一个地方。我们首次接触到它们在1.6.2节,在那里,它们被 “类型检查器用来跟踪一个变量”,这个变量能够在一个程序中的单一点拥有不同的类型,而这决定于达到这个“点”代码的逻辑路径。而对于泛型,类型检查器使用未决的类型来记住那些还没有被明确规定的类型,当类型检查器看到更多的代码后,这里将随时保持对它们进行调整的自由。
在第一行的后面,类型检查器已经非常肯定变量$w是个Wrapper,但是关于它的类型实参是什么,这里还没有明确的指引。它想起以前曾经看到这个对象被当作类型Wrapper进行使用,但是int的类型实参是个未决的类型。于是,它继续向上查看相关调用$w->setValue('a string'),类型检查器查看变量$w的类型,来看这个调用是否合法。当它看到未决的类型实参时,它将把字符串添加到未决的类型中去,而不是抛出一个错误。到此为止,就类型检查器来说,变量$w或者是Wrapper或者是Wrapper。
而对于读者来说,直觉上并不是这样的:很明显在$w内有个字符串。但是类型检查器不知道Wrapper的语义:它并不明白Wrapper只包含单个值。类型检查器所知晓的就是$w好像被当成Wrapper进行使用,还好像是个Wrapper。
当检查到一个未决的类型实参违反某个类型标注的时候,它将变成一个“已决的类型”。这个例子将展示一切相关的内容:

function takes_wrapper_of_int(Wrapper<int> $w): void {
  // ...
}
function main(): void {
  $w = new Wrapper(20);
  takes_wrapper_of_int($w);
  $w->setValue('a string');??// 错误!
}

这次,类型检查器将在最后一行报告一个错误。当变量$w被传递给函数takes_wrapper_of_int()时,检查到它违反了函数的形参类型标注。在这点上,变量$w的类型是“已决的”。类型检查器已经看到变量$w应该是一个Wrapper类型的确凿证据。既然这个类型是“已决的”了,类型检查器在对setValue()方法的调用检查上也就不会宽大处理了。在一个已决的类型Wrapper的Wrapper实例上调用“setValue('a string')”是非法的,所以类型检查器报告了一个错误。

相关文章
|
安全 PHP C++
《Hack与HHVM权威指南》——导读
在Facebook公司的大部分发展历程中,每隔几个月就会举办“黑客马拉松(hackathons)”活动,活动的目的在于鼓励工程师们碰撞出好的想法,而这些好的想法并不是和他们的日常工作相关的,他们自由组队,然后在一两天的时间内做出一些非常有意思的事情。
2111 0