W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
下面是一些類(lèi)型常量在嘗試決定是使用它們還是泛型類(lèi)型參數(shù)化時(shí)可能有用的示例。
引用類(lèi)型常量與引用靜態(tài)類(lèi)常量一樣簡(jiǎn)單。
<?hh
namespace Hack\UserDocumentation\TypeConstants\Exampes\Examples\Referencing;
/*
With generics, you reference the type parameter through explicit type
parameterization declarations on all classes, functions, traits and interfaces
using that type. In some cases that could be redundant because we know
the type implicitly by knowing the type of the parent class.
*/
abstract class UserG<Tg as arraykey> {
public function __construct(private Tg $id) {}
public function getID(): Tg {
return $this->id;
}
}
class AppUserG<Tg as int> extends UserG<Tg> {}
// Still have to parameterize this function even though we know what Tg is.
function get_id_from_userg<Tg as arraykey>(AppUserG $ug): Tg {
return $ug->getID();
}
/*
With type constants, we can avoid having to declare the type parameter on a
child class and function. The only thing needed in a child class is the
concrete type binding on the abstract type constant of the parent. Otherwise,
we just use reference the type constant as a normal property.
*/
abstract class UserTC {
abstract const type Ttc as arraykey;
public function __construct(private this::Ttc $id) {}
public function getID(): this::Ttc {
return $this->id;
}
}
class AppUserTC extends UserTC {
const type Ttc = int;
}
function get_id_from_userTC(AppUserTC $uc): AppUserTC::Ttc {
return $uc->getID();
}
function run(): void {
$aug = new AppUserG(-1);
var_dump(get_id_from_userg($aug));
$autc = new AppUserTC(-2);
var_dump(get_id_from_userTC($autc));
}
run();
Output
int(-1)
int(-2)
對(duì)于在類(lèi)中聲明的類(lèi)型常量,可以提供約束和具體類(lèi)型。當(dāng)提供約束時(shí),這允許類(lèi)型常量被子類(lèi)覆蓋。接口不支持此功能。
<?hh
namespace Hack\UserDocumentation\TypeConstants\Exampes\Examples\Overriding;
abstract class BaseAbstract {
abstract const type T;
}
class ChildWithConstraint extends BaseAbstract {
// We can override this constraint in a child of this concrete class
// since we provided an explicit as constraint.
const type T as ?arraykey = ?arraykey;
}
class ChildOfChildWithNoConstraint extends ChildWithConstraint {
// Cannot override this in a child of this class.
const type T = arraykey;
}
class ChildOfChildOfChildWithNoConstraint extends ChildOfChildWithNoConstraint {
// Type error here
const type T = string;
}
function run(): void {
echo "No real output!";
}
run();
Output
No real output!
您可以使用類(lèi)型常量作為類(lèi)實(shí)例方法的輸入。
<?hh
namespace Hack\UserDocumentation\TypeConstants\Exampes\Examples\Instance;
abstract class Box {
abstract const type T;
public function __construct(private this::T $value) {}
public function get(): this::T {
return $this->value;
}
public function set(this::T $val): this {
$this->value = $val;
return $this;
}
}
class IntBox extends Box {
const type T = int;
}
function run(): void {
$ibox = new IntBox(10);
$ibox->set(11);
var_dump($ibox);
invariant($ibox instanceof Box, 'Upcast to Box');
var_dump($ibox);
// CHECK THIS -- THIS SHOULD (?) ERROR BUT THE TYPECHECKER IS NOT CATCHING IT
// This will be an error because 'this::T' in '$box' may not be an int
$ibox->set(1337);
var_dump($ibox);
// This is not an error because the type checker knows that the type
// returned by $box->get(), is the same accepted by $box->set()
$ibox->set($ibox->get());
var_dump($ibox);
}
run();
Output
object(Hack\UserDocumentation\TypeConstants\Exampes\Examples\Instance\IntBox)#1 (1) {
["value":"Hack\UserDocumentation\TypeConstants\Exampes\Examples\Instance\Box":private]=>
int(11)
}
object(Hack\UserDocumentation\TypeConstants\Exampes\Examples\Instance\IntBox)#1 (1) {
["value":"Hack\UserDocumentation\TypeConstants\Exampes\Examples\Instance\Box":private]=>
int(11)
}
object(Hack\UserDocumentation\TypeConstants\Exampes\Examples\Instance\IntBox)#1 (1) {
["value":"Hack\UserDocumentation\TypeConstants\Exampes\Examples\Instance\Box":private]=>
int(1337)
}
object(Hack\UserDocumentation\TypeConstants\Exampes\Examples\Instance\IntBox)#1 (1) {
["value":"Hack\UserDocumentation\TypeConstants\Exampes\Examples\Instance\Box":private]=>
int(1337)
}
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話(huà):173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: