W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
除了完全支持一刀切的PHP array
容器類型,Hack允許將額外的打字放置在數(shù)組上,并提供了一些實(shí)現(xiàn)更專門的集合模式的類。
在Hack中的數(shù)組行為類似于Generics可以提供關(guān)于它們?nèi)绾螌iT的附加類型信息。例如,一個(gè)無(wú)索引的字符串?dāng)?shù)組采用形式array<string>。類似地,對(duì)于索引數(shù)組,可以首先指定鍵類型(int或string),后跟值類型。因此,帶有字符串鍵和浮點(diǎn)值的字典可能看起來(lái)像array<string, float>。
由于數(shù)組的值側(cè)本身可能是一個(gè)數(shù)組(或一個(gè)Generic類),因此類型專門化可以嵌套,array<int, array<string, string>>其中包含數(shù)字索引的數(shù)組包含字符串字典。
<?hh
namespace Hack\UserDocumentation\Collections\Intro\Examples\Arr;
// array<string, string> is an array map with string keys and string values
function array_as_map(array<string, string> $arr): string {
$r = substr(str_shuffle('ABCDEF'), 0, 1); // random letter
return array_key_exists($r, $arr) ? $arr[$r] : 'Z';
}
// array<int> is an array vector with integer keys and integer values
function array_as_vector(array<int> $arr): int {
$r = rand(0, 10);
return array_key_exists($r, $arr) ? $arr[$r] : PHP_INT_MAX;
}
function run(): void {
$v = array(100, 200, 300, 400);
$v[] = 500; // element 5, value 500
var_dump($v);
var_dump(array_as_vector($v));
$m = array('A' => 'California', 'B' => 'Oregon', 'C' => 'North Carolina');
$m['D'] = 'Florida';
var_dump($m);
var_dump(array_as_map($m));
}
run();
Output
array(5) {
[0]=>
int(100)
[1]=>
int(200)
[2]=>
int(300)
[3]=>
int(400)
[4]=>
int(500)
}
int(9223372036854775807)
array(4) {
["A"]=>
string(10) "California"
["B"]=>
string(6) "Oregon"
["C"]=>
string(14) "North Carolina"
["D"]=>
string(7) "Florida"
}
string(7) "Florida"
雖然PHP數(shù)組是非常通用的,但靈活性偶爾會(huì)在性能,正確性或可讀性方面付出代價(jià)。Hack Collection類旨在通過(guò)以普通容器模式的形式提供深度專門的數(shù)組對(duì)象版本來(lái)解決這些問(wèn)題:Vector, Map,和 Set。
hack有七個(gè)集合:
類型 | 描述 |
---|---|
Vector | 可變的,int 被索引的,有序的值序列。值可以是任何類型。所述indicies在開(kāi)始0 和結(jié)束處n-1 ,在那里n 是元件的數(shù)量。 |
ImmVector | 一個(gè)不變的版本Vector 。一旦ImmVector 被創(chuàng)建,元件不能改變,刪除或添加。 |
Map | 可變的string 或者int 索引的索引序列的值序列。值可以是任何類型。訂單被記住。這與array 使用中最相似。 |
ImmMap | 一個(gè)不變的版本Map 。一旦ImmMap 被創(chuàng)建,元件不能改變,刪除或添加。 |
Set | 可變的,有序的唯一值集。值只能是int 或string 。有在無(wú)鑰匙Set 。 |
ImmSet | 一個(gè)不變的版本Set 。一旦ImmSet 被創(chuàng)建,元件不能改變,刪除或添加。 |
Pair | 完全兩個(gè)值的不可變序列。鑰匙是0 和1 。它們與元組類似,但靈活性較差。 |
想象一下第三方功能聲明如下:
function foo(array<int, string> $arr): void {}
這是array一個(gè)帶有順序整數(shù)鍵的向量風(fēng)格數(shù)組嗎?或者可能是map具有潛在非順序整數(shù)鍵的風(fēng)格數(shù)組?這個(gè)數(shù)組中的值是否唯一?
現(xiàn)在想象這個(gè)函數(shù)聲明:
function bar(Vector<string> $vec): void {}
通過(guò)查看函數(shù)簽名,我們知道這些整數(shù)鍵是有序的和順序的。實(shí)際的關(guān)鍵數(shù)字可能與其持有的東西相關(guān)程度不大。
類似地,如果函數(shù)聲明是:
function bar(Set<string> $set): void {}
然后我們意識(shí)到這些整數(shù)鍵是不相關(guān)的,并且包含在該參數(shù)中的字符串都將具有唯一的值。
在明顯的好處Vectors,并Sets有該按鍵可以由運(yùn)行時(shí)被忽略。對(duì)于Vectors,這意味著連續(xù)排列值并基于索引進(jìn)行快速查找和迭代。在Sets 的情況下,它實(shí)際上意味著(作為實(shí)現(xiàn)細(xì)節(jié))將內(nèi)部結(jié)構(gòu)轉(zhuǎn)換為內(nèi)部,使用值作為鍵(必須是唯一的),并忽略陣列對(duì)的另一半。這是PHP代碼中已經(jīng)提供的一種模式,但它消除了必須記住陣列內(nèi)部的認(rèn)知開(kāi)銷,并且以比腳本代碼能夠更有效的方式進(jìn)行操作。
以下是密鑰收集類的操作的典型的攤銷時(shí)間復(fù)雜度array:
CLASS | ACCESS | ITERATION | INSERT | REMOVAL |
---|---|---|---|---|
Vector | O(1) | O(n) | O(n) | O(n) |
Map | O(1) | O(n) | O(1) | O(1) |
Set | O(1) | O(n) | O(1) | O(1) |
Pair | O(1) | O(1) | N/A | N/A |
array | O(1) | O(n) | O(1) | O(1) |
與可讀性有關(guān),Hack類型檢查器不能指出,例如,您的代碼的上下文是否將array使用的向量傳遞給array使用類似地圖的參數(shù)的函數(shù)。例如,以下代碼通過(guò)類型檢查器。
<?hh
namespace Hack\UserDocumentation\Collections\Intro\Examples\ArrTypeCheck;
// This is a array used like a map, but it can be passed an array used like
// a vector.
function array_as_map(array<int, int> $arr): int {
$r = rand(0, 10); // random letter
return array_key_exists($r, $arr) ? $arr[$r] : PHP_INT_MAX;
}
function run(): void {
$v = array(100, 200, 300, 400);
$v[] = 500; // element 5, value 500
var_dump($v);
var_dump(array_as_map($v));
}
run();
Output
array(5) {
[0]=>
int(100)
[1]=>
int(200)
[2]=>
int(300)
[3]=>
int(400)
[4]=>
int(500)
}
int(9223372036854775807)
但是,如果你把代碼相似的風(fēng)格,而是使用Vector
和Map
,則typechecker很容易分辨的意圖。
<?hh
namespace Hack\UserDocumentation\Collections\Intro\Examples\MapTypeCheck;
// array<string, string> is an array map with string keys and string values
function array_as_map(Map<int, int> $arr): int {
$r = rand(0, 10); // random letter
return array_key_exists($r, $arr) ? $arr[$r] : -1;
}
function run(): void {
$v = Vector { 100, 200, 300, 400 };
$v[] = 500; // element 5, value 500
var_dump($v);
// The call to array_as_map will not typecheck because you are trying to pass
// a Vector into a function expecting a Map. You will also get a runtime
// error as well trying to do this.
var_dump(array_as_map($v));
}
run();
Output
object(HH\Vector)#1 (5) {
[0]=>
int(100)
[1]=>
int(200)
[2]=>
int(300)
[3]=>
int(400)
[4]=>
int(500)
}
Catchable fatal error: Argument 1 passed to Hack\UserDocumentation\Collections\Intro\Examples\MapTypeCheck\array_as_map() must be an instance of HH\Map, HH\Vector given in /data/users/joelm/user-documentation/guides/hack/23-collections/01-introduction-examples/map-typecheck.php.type-errors on line 9
使用Hack集合可以讓類型檢查器使用更多的數(shù)據(jù)來(lái)嘗試確定你的代碼中是否有打字問(wèn)題。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: