我想創建一個抽象類,它接受一個類型參數,並且該類的構造函數應該傳遞另一個動作,例如。泛型類型參數通配符
abstract class Action<Tc> {
public function __construct(private ?Action<*> $onSuccess = null) {}
}
我該如何表達一個類型參數通配符ie。 「?」 (Java)或「_」(Scala)在Hack?
我想創建一個抽象類,它接受一個類型參數,並且該類的構造函數應該傳遞另一個動作,例如。泛型類型參數通配符
abstract class Action<Tc> {
public function __construct(private ?Action<*> $onSuccess = null) {}
}
我該如何表達一個類型參數通配符ie。 「?」 (Java)或「_」(Scala)在Hack?
不確定通配符,但可以實現你想要的嗎?
<?hh
abstract class Action<T1 as Action, T2> {
public function __construct(private ?T1 $onSuccess = null, private ?T2 $bla = null) {}
}
class ActionA<T1 as Action, T2> extends Action<T1, T2> {}
class ActionB<T1 as Action, T2> extends Action<T1, T2> {}
class ActionC<T1 as Action, T2> extends Action<T1, T2> {}
$action = new ActionA(new ActionB(new ActionC(null)));
var_dump($action);
當我跑這對HHVM 3.1.0,我得到: 「沒有錯誤」
object(ActionA)#1 (2) {
["onSuccess":"Action":private]=>
object(ActionB)#2 (2) {
["onSuccess":"Action":private]=>
object(ActionC)#3 (2) {
["onSuccess":"Action":private]=>
NULL
["bla":"Action":private]=>
NULL
}
["bla":"Action":private]=>
NULL
}
["bla":"Action":private]=>
NULL
}
而且3.1.0類型檢查也返回。
但是,關於抽象類的T1 as Action
聲明似乎沒有強制執行。舉例來說,我可以改變的實例行:
$action = new ActionA(new ActionB(new ActionC(new DateTime())));
它沿着細哼唱,與typechecker返回沒有錯誤依然。這是在將類定義帶入<?hh // strict
的文件之後。
所以不是你的答案,但也許關閉?上面的行爲可能表明Hack有這種模式的一些問題?
'T1 as Action'省略了'Action
哈克沒有通配符類型的參數,現在,所以最接近你可以得到實際上是指定你實際上並不需要一個虛擬的類型參數,例如,
abstract class Action<Tc, Ta> {
public function __construct(private ?Action<Ta> $onSuccess = null) {}
// ...
}
根據如何正是你使用$onSuccess
成員變量,你可能希望它是Action<T>
一些具體子類稍後確定,所以你可能想是這樣的:
abstract class Action<Tc, Ta, To as Action<Ta>> {
public function __construct(private ?To $onSuccess = null) {}
// ...
}
然而,我懷疑是否上面的「虛擬」類型以上AR e真的是一個虛擬 - Action<T>
的絕大多數用例都會關心T
究竟是什麼,否則您將如何使用Action<T>
? (當然在極少數情況下,您並不關心呼叫站點上的T
,但它們很罕見,所以我鼓勵您在構建此功能時考慮是否確實是您的情況。)
考慮到你對Github上的desugaring的評論,[[link](https://github.com/facebook/hhvm/issues/3183)),這種行爲總是有意義的。然而,Action
我並不是Hack方面的專家,但在我看來,你的設置相當於讓'Action'從一個單形類繼承,比如說'ActionBase',它暴露了所有'Action <*>'使用的接口。如果你正在設計代碼,你可以用這種方式重構你的動作類。 – didierc