基础类型

PHP中主要的基础类型可以在Hack中进行显式类型标注。包含:

  • bool
  • int
  • float
  • string
  • array
  • resource
<?hh

namespace Hack\UserDocumentation\Types\TypeSystem\Examples\Primitive;

class A {
protected float $x;
public string $y; public function __construct() {
$this->x = 4.0;
$this->y = "Day";
}
public function foo(bool $b): float {
return $b ? 2.3 * $this->x : 1.1 * $this->x;
}
} function bar(): string {
// local variables are inferred, not explicitly typed
$a = new A();
if ($a->foo(true) > 8.0) {
return "Good " . $a->y;
}
return "Bad " . $a->y;
} var_dump(bar());

Output

string(8) "Good Day"

别名类型

Hack不支持别名基础类型,所以以下用于类型标准的写法是无效的:

  • boolean
  • integer
  • real
  • double
  • void

void 是一种特殊的基础类型,代表函数或方法没有可监听的返回值。在定义了void的函数体中,可以使用return;。

NOTE: void 只能在方法和函数的返回值处定义,不能用在属性或参数上。

<?hh

namespace Hack\UserDocumentation\Types\TypeSystem\Examples\Void;

class A {
protected float $x;
public string $y; public function __construct() {
$this->x = 4.0;
$this->y = "Day";
}
public function foo(bool $b): float {
return $b ? 2.3 * $this->x : 1.1 * $this->x;
}
} // void can only be used as a return types
function bar(): void {
// local variables are inferred, not explicitly typed
$a = new A();
if ($a->foo(true) > 8.0) {
echo "Good " . $a->y;
} else {
echo "Bad " . $a->y;
}
} bar();

Output

Good Day

In Async

It is relatively common for async functions to return Awaitable. This means that while the function itself is returning an awaitable, the result of that awaitable will have no value. This, in essence, means the async function did some operation asynchronously that did not require a return value to the caller.

noreturn

noreturn 是一种特殊的基础类型,代表函数或静态方法永不返回值。与void有点相似,但如果定义了noreturn,在函数体中连return;语句都不能出现。

noreturn 用于标识指定函数或静态方法总是抛出异常或以某种方式终止程序执行。

<?hh

namespace Hack\UserDocumentation\Types\TypeSystem\Examples\NoReturn;

class A {
protected float $x;
public string $y; public function __construct() {
$this->x = 4.0;
$this->y = "Day";
}
public function foo(bool $b): float {
return $b ? 2.3 * $this->x : 1.1 * $this->x;
} // no return cannot be on an instance method
// only functions and static class methods
public static function baz(bool $b): noreturn {
if ($b) {
throw new \Exception("No Return");
} else {
exit(1);
}
return; // Even this will cause type-errors
}
} // void can only be used as a return types
function bar(): void {
// local variables are inferred, not explicitly typed
$a = new A();
if ($a->foo(true) > 8.0) {
echo "Good " . $a->y;
} else {
echo "Bad " . $a->y;
}
A::baz(false);
} bar();

Output

Good Day

注意:

仅用于静态方法与函数

noreturn can only be used in function or static method returns.

Instance methods cannot be noreturn. This is due to the order in which the typechecker's analysis phases happen. The return type of an instance method call cannot be determined during control flow analysis because it needs to know the type on the left-hand side of the ->, and the results of type inference aren't available yet. This isn't an issue for calls to static methods, since those can be resolved before types have been inferred.

noreturn is not applicable to properties or parameters.

对象

You can use the name of any built-in or custom class or interface.

<?hh

namespace Hack\UserDocumentation\Types\TypeSystem\Examples\Obj;

class Z {
public function create_A(): A {
return new A();
}
} class A {
protected float $x;
public string $y; public function __construct() {
$this->x = 4.0;
$this->y = "Day";
}
public function foo(bool $b): float {
return $b ? 2.3 * $this->x : 1.1 * $this->x;
}
} // We are taking a Z and returning an object of type A
function baz(Z $z): A {
return $z->create_A();
} function bar(): string {
// local variables are inferred, not explicitly typed
$z = new Z();
$a = baz($z);
if ($a->foo(true) > 8.0) {
return "Good " . $a->y;
}
return "Bad " . $a->y;
} var_dump(bar());
Output
string(8) "Good Day"
mixed

mixed is essentially a catch-all type that represents any possible Hack value (including null and void).

<?hh

namespace Hack\UserDocumentation\Types\TypeSystem\Examples\Mixed;

class A {
public float $x;
protected string $y; public function __construct() {
$this->x = 4.0;
$this->y = "Day";
}
// mixed is the most lax type. Use it only when necessary
public function foo(bool $b): mixed {
return $b ? 2.3 * $this->x : $this->y;
}
} function bar(): string {
// local variables are inferred, not explicitly typed
$a = new A();
$v = $a->foo(false);
// Since A::foo() returns a mixed, we need to do various checks to make sure
// that we let the typechecker know understand what is coming back.
if (is_float($v)) {
return "No String";
}
invariant(is_string($v), "Something went wrong if this isn't true");
return "Good " . $v;
} var_dump(bar());
Output
string(8) "Good Day"

Use sparsely

There are valid uses for mixed, but generally you want to be as specific as possible with your typing since the typechecker can only do so much with mixed given its constraints are so lax.

this

this can only be used as a return type annotation on a method of a class. this signifies that the method returns an object of the same class on which the method is defined.

The primary purpose of return this is to allow chaining of method calls on the instance of the class itself or its subclasses.

<?hh

namespace Hack\UserDocumentation\Types\TypeSystem\Examples\ThisChaining;

class Vehicle {
private ?int $numWheels;
private ?string $make; public function setNumWheels(int $num): this {
$this->numWheels = $num;
return $this;
} public function setMake(string $make): this {
$this->make = $make;
return $this;
}
} class Car extends Vehicle {
private ?bool $autoTransmission; public function setAutomaticTransmission(bool $automatic): this {
$this->autoTransmission = $automatic;
return $this;
}
} class Hybrid extends Car {
private ?bool $pluggable; public function setPluggable(bool $pluggable): this {
$this->pluggable = $pluggable;
return $this;
} public function drive(): void {}
} function run(): void {
$h = new Hybrid();
// $h->NumWheels(4) returns the instance so you can immediately call
// setMake('Tesla') in a chain format, and so on. Finally culminating in an
// actionable method call, drive().
$h->setNumWheels(4)
->setMake('Tesla')
->setAutomaticTransmission(true)
->setPluggable(true)
->drive();
var_dump($h);
} run();
Output
object(Hack\UserDocumentation\Types\TypeSystem\Examples\ThisChaining\Hybrid)#1 (4) {
["pluggable":"Hack\UserDocumentation\Types\TypeSystem\Examples\ThisChaining\Hybrid":private]=>
bool(true)
["autoTransmission":"Hack\UserDocumentation\Types\TypeSystem\Examples\ThisChaining\Car":private]=>
bool(true)
["numWheels":"Hack\UserDocumentation\Types\TypeSystem\Examples\ThisChaining\Vehicle":private]=>
int(4)
["make":"Hack\UserDocumentation\Types\TypeSystem\Examples\ThisChaining\Vehicle":private]=>
string(5) "Tesla"
}

this on a static method means that a class method returns an object of the same class as the calling method. You can use it to return an instance of an object from a static class method where you are returning something like new static().

<?hh

namespace Hack\UserDocumentation\Types\TypeSystem\Examples\ThisStatic;

class A {
protected float $x;
public string $y; // typechecker error if constructor isn't final because new static() cannot
// be called to return an instance of a subclass
final protected function __construct() {
$this->x = 4.0;
$this->y = "Day";
} public function foo(bool $b): float {
return $b ? 2.3 * $this->x : 1.1 * $this->x;
} // The this type annotation allows you to return an instance of a type
public static function create(int $x): this {
$instance = new static();
if ($x < 4) {
$instance->x = floatval($x);
}
return $instance;
}
} function bar(): string {
// local variables are inferred, not explicitly typed
// There is no public constructor, so call A's create() method
$a = A::create(2);
if ($a->foo(true) > 8.0) {
return "Good " . $a->y;
}
return "Bad " . $a->y;
} var_dump(bar());
Output
string(7) "Bad Day"

num

num 是int 与 float的一种特殊联合类型。正常情况下,Hack里整型和浮点型是不兼容的类型。但对于很多数值操作的函数来说,传整型或浮点型差不多的情况下,就可以用num了。

<?hh

namespace Hack\UserDocumentation\Types\TypeSystem\Examples\Num;

class A {
protected num $x;
public string $y; public function __construct(num $x) {
$this->x = $x;
$this->y = "Day";
}
public function foo(bool $b): num {
return $b ? 2.3 * $this->x : 1.1 * $this->x;
}
// The $x property can be either a float or int
public function setNum(num $x): void {
$this->x = $x;
}
} function check(A $a): string {
if ($a->foo(true) > 8.0) {
return "Good " . $a->y;
}
return "Bad " . $a->y;
} function bar(): string {
// local variables are inferred, not explicitly typed
// Setting the $x property in A to an int
$a = new A(4);
$ret = check($a);
// Now setting to a float
$a->setNum(0.4);
$ret .= "##" . check($a);
return $ret;
} var_dump(bar());
Output
string(17) "Good Day##Bad Day"

arraykey

arraykey is special union type of int and string. Arrays and collection types can be keyed by int or string. Suppose, for example, an operation was performed on an array to extract the keys, but you didn't know the type of the key. You were left with using mixed or doing some sort of duplicative code. arraykey resolves that issue.

<?hh

namespace Hack\UserDocumentation\Types\TypeSystem\Examples\ArrayKey;

class A {
protected float $x;
public string $y; public function __construct(float $x) {
$this->x = $x;
$this->y = "Day";
}
public function foo(bool $b): float {
return $b ? 2.3 * $this->x : 1.1 * $this->x;
}
} // This function can return either a string or an int since it is typed to
// return an arraykey
function bar(): arraykey {
// local variables are inferred, not explicitly typed
$a = new A(0.9);
if ($a->foo(true) > 8.0) {
return "Good " . $a->y;
}
return 5;
} var_dump(bar());
Output
int(5)

XHP

There are two XHP interfaces that are used when typing XHP objects: XHPChild and XHPRoot.

XHPRoot is any object that is an instance of an XHP class.

XHPChild is the set of valid types for echoing within an XHP context (e.g., echo

{$xhpobj}

Hack语言的类型系统的更多相关文章

  1. Hack语言类型化简介

    在typechecker的配合下,Hack语言的类型化能力是Hack其他功能特性的基石.开发Hack语言的主要动机也正是为代码提供显式类型标注以便对代码进行类型一致性和潜在错误分析. 这是用于对比Ha ...

  2. Facebook的Hack语言三大看点

    Hack语言主要有三大看点:类型化.异步.集合. Hack最基础的特性就是类型标注.PHP5已经开始支持对象的类型化,PHP7也提供了标量类型化声明.Hack提供了全面的类型标注支持,与其typech ...

  3. Facebook Hack 语言 简介

    1. Hack 是什么? Hack 是一种基于HHVM(HipHop VM 是Facebook推出的用来执行PHP代码的虚拟机,它是一个PHP的JIT编译器,同时具有产生快速代码和即时编译的优点.)的 ...

  4. Hack语言特性之类型化

    Hack最基础的特性就是类型标注.PHP5已经开始支持对象的类型化,PHP7也提供了标量类型化声明.Hack提供了全面的类型标注支持,与其typecher配合使用,还可以实现快速.前置静态类型验证. ...

  5. 【编程笔记】Unity3D语言的类型系统--C#的类型系统

    几乎所有的编程语言都有自己的类型系统. 而编程语言更是常常按照其类型系统而被分为强类型语言/弱类型语言.安全类型语言/不安全类型语言.静态类型语言/动态类型语言等. 而C#的类型系统是静态.安全,并且 ...

  6. Hack 语言学习/参考---1.3 Summary

    Summary Hack provides the following, non-exhaustive list of features: Ability to annotate function a ...

  7. Hack 语言学习/参考---1.2 Hack Background

    Hack Background Facebook was initially built with PHP. Parameters and return types were specified in ...

  8. Hack 语言学习/参考---1.1 What is Hack?

    What is Hack?¶ Hack is a language for HHVM that interopates seamlessly with PHP. The barrier to entr ...

  9. Hack 语言学习/参考---1.Hack 语言

    Table of Contents What is Hack? Hack Background Summary Hack is a language for HHVM that interopates ...

随机推荐

  1. CocoaPods 使用

    为什么要使用这个玩意呢,最近在使用swift开发项目,使用 swift 开源库的时候,在git上下载后居然不知道哪些是必须文件,还要思考下,看看哪些是需要的(不像原来oc开源库,一目了然),网上使用d ...

  2. MVVM架构~Knockoutjs系列之验证机制的引入

    返回目录 对于Knockoutjs本身来说,没有提供验证模块,不过,有第三方的扩展,就像你为jquery库作extensions一样,这讲中我将介绍一个Knockout插件扩展,knockout.va ...

  3. 爱上MVC3~为下拉列表框添加一个自定义验证规则

    回到目录 开发它的原因: 之前的同事,也是我的哥们,问我下拉列表框是否可以支持验证,这个问题看似简单,但确实MVC里有为我们提供,所以,只能自己写个扩展了,即自己写一个attribute特性,让它继承 ...

  4. 22.编写一个类A,该类创建的对象可以调用方法showA输出小写的英文字母表。然后再编写一个A类的子类B,子类B创建的对象不仅可以调用方法showA输出小写的英文字母表,而且可以调用子类新增的方法showB输出大写的英文字母表。最后编写主类C,在主类的main方法 中测试类A与类B。

    22.编写一个类A,该类创建的对象可以调用方法showA输出小写的英文字母表.然后再编写一个A类的子类B,子类B创建的对象不仅可以调用方法showA输出小写的英文字母表,而且可以调用子类新增的方法sh ...

  5. Atitit.java c#这类编程语言的设计失败点attilax总结

    Atitit.java c#这类编程语言的设计失败点attilax总结 1. Npe1 2. Api粒度过小而又没有提供最常用模式1 3. checked exception(jeig n jyejy ...

  6. Atitit 图像处理之仿油画效果 Oilpaint油画滤镜 水彩画 漫画滤镜 v2

    Atitit 图像处理之仿油画效果 Oilpaint油画滤镜 水彩画 漫画滤镜 v2 1.1. 具体源码参考1 2. ,油画 水彩画具有几个比较明显的特点如下:1 2.1. 明暗层次(灰度)较少  也 ...

  7. Atitit 图像处理 公共模块 矩阵扫描器

    Atitit 图像处理 公共模块 矩阵扫描器 1.1. 调用说明对矩阵像素遍历处理调用1 2. 矩阵扫描器主题结构1 2.1. 主要说明 从像素点开始填充矩阵1 2.2. 得到模板中心点所对应的图像坐 ...

  8. Android 实现应用升级方案(暨第三方自动升级服务无法使用后的解决方案)

    第三方推送升级服务不再靠谱: 以前在做Android开发的时候,在应用升级方面都是使用的第三方推送升级服务,但是目前因为一些非技术性的问题,一些第三方厂商不再提供自动升级服务,比如友盟,那么当第三方推 ...

  9. jQuery LigerUI 最新版压缩包(含chm帮助文档、源码、donet权限示例)

    jQuery LigerUI 最新版压缩包 http://download.csdn.net/download/heyin12345/4680593 jQuery LigerUI 最新版压缩包(含ch ...

  10. html_01之基础标签

    1.嵌套规则:①行内不能嵌套块:②p不能嵌套块:③非布局元素不要嵌套div: 2.标准属性:①id:定义元素唯一名称(a.布局时用:b.JS用):②title:鼠标移入时提示的文字:③class:定义 ...