一個(gè)形狀的一組由零個(gè)或多個(gè)數(shù)據(jù)字段放在一起作為一個(gè)整體;它是一個(gè)數(shù)組的鍵是由Hack typechecker跟蹤。
例如:
<?hh
shape ('x' => int , 'y' => int )
形狀的定義包含一組有序的字段,每個(gè)字段都有一個(gè)名稱和一個(gè)類型。在上述情況下,形狀由兩個(gè)int字段組成,分別是名稱'x'和名稱'y'。
<?hh
namespace Hack\UserDocumentation\Shapes\Introduction\Examples\Intro;
type Point = shape('x' => int, 'y' => int);
class C1 {
private Point $origin;
private function __construct(int $x = 0, int $y = 0) {
$this->origin = shape('x' => $x, 'y' => $y);
}
}
function distance_between_2_Points(Point $p1, Point $p2): float {
// access shape info via keys in the shape map, in this case `x` and `y`
$dx = $p1['x'] - $p2['x'];
$dy = $p1['y'] - $p2['y'];
return sqrt($dx*$dx + $dy*$dy);
}
function run(): void {
$p1 = shape('x' => 4, 'y' => 6);
$p2 = shape('x' => 9, 'y' => 2);
var_dump(distance_between_2_Points($p1, $p2));
}
run();
Output
float(6.4031242374328)
雖然我們可以直接使用形狀類型,但是通常創(chuàng)建別名(例如Point上面的名稱)是方便的,而是使用它。
使用其名稱作為在對(duì)應(yīng)形狀類型的形狀上操作的下標(biāo)表達(dá)式中的鍵來(lái)訪問(wèn)形狀中的字段。例如:
字段的名稱可以用兩種可能的形式之一寫成:
請(qǐng)注意,整數(shù)文字不能直接用作字段名稱。
給定形狀定義中的所有字段的名稱必須是不同的,并且具有相同的形式。
例如,當(dāng)從函數(shù)返回形狀時(shí),必須考慮所有字段; 否則Hack typechecker會(huì)引發(fā)錯(cuò)誤。
<?hh
namespace Hack\UserDocumentation\Shapes\Introduction\Examples\Fields;
type user = shape('id' => int, 'name' => string);
class UserClass {
public static function create_user(int $id, string $name): user {
$user = shape();
$user['id'] = $id;
return $user;
}
}
function run(): void {
var_dump(UserClass::create_user(1, 'James'));
}
run();
Output
array(1) {
["id"]=>
int(1)
}
在上面的例子中,我們忘記設(shè)置該形狀的名稱字段。請(qǐng)注意,HHVM仍將運(yùn)行代碼,因?yàn)樗皇歉采w在下面的數(shù)組。
typechecker將可選項(xiàng)和可空值混合。shape('name' => ?string)將同時(shí)匹配shape('name' => null)和shape()。因此,如果省略一個(gè)可空的字段,那么typechecker就不會(huì)引起錯(cuò)誤。但是,OutOfBoundsException如果您嘗試讀取省略的字段,則運(yùn)行時(shí)將會(huì)引發(fā)。
類常數(shù)可用于Shapes。
<?hh
namespace Hack\UserDocumentation\Shapes\Introduction\Examples\ClassConstants;
class C2 {
const string KEYA = 'x';
const string KEYB = 'y';
const int KEYX = 10;
const int KEYY = 23;
}
type PointS = shape(C2::KEYA => int, C2::KEYB => int);
type PointI = shape(C2::KEYX => int, C2::KEYY => int);
function print_pointS(PointS $p): void {
var_dump($p);
}
function print_pointI(PointI $p): void {
var_dump($p);
}
function run(): void {
print_pointI(shape(C2::KEYX => -1, C2::KEYY => 2));
print_pointS(shape(C2::KEYA => -1, C2::KEYB => 2));
}
run();
Output
array(2) {
[10]=>
int(-1)
[23]=>
int(2)
}
array(2) {
["x"]=>
int(-1)
["y"]=>
int(2)
}
在上面我們例子中的整數(shù)類常量的情況下,通過(guò)任意選擇,x坐標(biāo)被存儲(chǔ)在具有鍵10的元素中,而y坐標(biāo)被存儲(chǔ)在具有鍵23的元素中。
形狀不必具有與其相關(guān)聯(lián)的類型別名。這是一個(gè)在所有地方使用文字形狀語(yǔ)法的例子。
<?hh
namespace Hack\UserDocumentation\Shapes\Intro\Examples\Anonymous;
class C {
public function __construct(
private shape('real' => float, 'imag' => float) $prop) {}
public function setProp(shape('real' => float, 'imag' => float) $val): void {
$this->prop = shape('real' => $val['real'], 'imag' => $val['imag']);
}
public function getProp(): shape('real' => float, 'imag' => float) {
return $this->prop;
}
}
function main(): void {
$c = new C(shape('real' => -2.5, 'imag' => 1.3));
var_dump($c);
$c->setProp(shape('real' => 2.0, 'imag' => 99.3));
var_dump($c->getProp());
}
main();
Output
object(Hack\UserDocumentation\Shapes\Intro\Examples\Anonymous\C)#1 (1) {
["prop":"Hack\UserDocumentation\Shapes\Intro\Examples\Anonymous\C":private]=>
array(2) {
["real"]=>
float(-2.5)
["imag"]=>
float(1.3)
}
}
array(2) {
["real"]=>
float(2)
["imag"]=>
float(99.3)
}
形狀是數(shù)組; 即呼叫is_array()將返回true。但是,您可以使用不能使用形狀的數(shù)組執(zhí)行一些操作。
更多建議: