W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
某些類型(類,接口和特性)及其方法可以參數(shù)化; 也就是說,它們的聲明可以有一個(gè)或多個(gè)稱為類型參數(shù)的占位符名稱,當(dāng)實(shí)例化一個(gè)類或調(diào)用方法時(shí),它們通過類型參數(shù)與類型相關(guān)聯(lián)。具有這種占位符名稱的類型或方法分別稱為泛型類型或泛型方法。頂層函數(shù)也可以參數(shù)化,從而產(chǎn)生泛型函數(shù)。
一個(gè)泛型類的例子是Vector<T>從Hack集合實(shí)現(xiàn)。T被稱為一個(gè)類型參數(shù),這是使通用的。它可以保存任何類型的值,從int到類的一個(gè)實(shí)例。然而,對于類的任何實(shí)例化來說,一旦一個(gè)類型已經(jīng)被關(guān)聯(lián)T,就不能改變?yōu)楸3秩魏纹渌愋汀?/p>
<?hh
namespace Hack\UserDocumentation\Generics\Intro\Examples\Vec;
/* Signature of Vector
*
* class Vector<Tv> implements MutableCollection<Tv> {
* :
* }
*
*/
function main_vec(): void {
$x = Vector {1, 2, 3, 4}; // T is associated with int
var_dump($x);
$y = Vector {'a', 'b', 'c', 'd'}; // T is associated with string
var_dump($y);
}
main_vec();
Output
object(HH\Vector)#1 (4) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
}
object(HH\Vector)#2 (4) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
string(1) "c"
[3]=>
string(1) "d"
}
$x是一個(gè)Vector<int>,$y而是一個(gè)Vector<string>。A Vector和 Vector不是相同的類型。
方法和功能也可以是通用的。一個(gè)用例是當(dāng)他們需要操縱泛型類時(shí):
<?hh
namespace Hack\UserDocumentation\Generics\Intro\Examples\GenericMethods;
// Testing generic methods in a non-generic class.
class Box<T> {
public T $value;
public function __construct(T $v) {
$this->value = $v;
}
}
function swap<T>(Box<T> $a, Box<T> $b) : void {
$temp = $a->value;
$a->value = $b->value;
$b->value = $temp;
}
function do_int_swap(): void {
$y = new Box(3);
$z = new Box(4);
echo $y->value." ".$z->value;
swap($y, $z);
echo $y->value." ".$z->value;
}
function do_string_swap(): void {
$y = new Box('a');
$z = new Box('b');
echo $y->value." ".$z->value;
swap($y, $z);
echo $y->value." ".$z->value;
}
function doAll(): void {
do_int_swap();
do_string_swap();
}
doAll();
Output
3 44 3a bb a
上面的例子展示了一個(gè)swap<T>()在泛型Box<T>類上運(yùn)行 的泛型函數(shù)。
泛型允許開發(fā)人員編寫一個(gè)具有任何類型參數(shù)的類或方法,同時(shí)保持類型安全。沒有泛型,完成一個(gè)類似的模型將需要?jiǎng)?chuàng)建BoxInt和BoxString類,并很快得到冗長?;蛘撸覀兛梢园阉?value當(dāng)作一個(gè)mixed類型來進(jìn)行instanceof()檢查,這意味著將一個(gè)字符串插入到一個(gè)int框中不會(huì)引發(fā)類型檢查錯(cuò)誤,而只會(huì)在運(yùn)行時(shí)發(fā)現(xiàn)。
泛型類型或方法的arity是為該類型或方法聲明的類型參數(shù)的數(shù)量。因此,類Vector有arity 1.哈克庫通用容器類Map實(shí)現(xiàn)了一個(gè)有序的,字典樣式的集合。這種類型有arity 2,并且使用了一個(gè)鍵類型和一個(gè)值類型,Map<int, Employee>例如,這個(gè)類型可以用來表示由一個(gè)整數(shù)員工編號(hào)索引的一組Employee對象。
在通用參數(shù)列表中,參數(shù)名稱必須
在以下情況下,類Vector有一個(gè)類型參數(shù),Tv所以有arity 1.方法map也有一個(gè)類型參數(shù)Tu,所以有arity 1。
final class Vector<Tv> implements MutableVector<Tv> {
…
public function map<Tu>((function(Tv): Tu) $callback): Vector<Tu> { … }
}
在以下的情況下,類Map
有兩個(gè)類型參數(shù),Tk
并且Tv
,因此具有元數(shù)2.方法zip
具有一個(gè),Tu
,所以有元數(shù)1。
final class Map<Tk, Tv> implements MutableMap<Tk, Tv> {
…
public function zip<Tu>(Traversable<Tu> $iter): Map<Tk, Pair<Tv, Tu>> { … }
}
在以下情況下,函數(shù)maxValue具有一個(gè)類型參數(shù)T,因此具有參數(shù)1。
function maxValue<T>(T $p1, T $p2): T { … }
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)系方式:
更多建議: