無論左側參數的方差,約束在下面的聲明放在Ta
和Tb
失敗類型檢測:爲什麼不能將全局上界約束變爲協變,而下界約束在Hack中是否是逆變的?
class A<+TCov, -TCon, [±]Ta as TCov, [±]Tb super TCon> {
public function __construct(private Ta $ta, private Tb $tb) {}
// [various methods making use of Ta and Tb]
}
值得一提的是,空類聲明不會引發錯誤,但一旦約束參數使用(中給出了自己的變化,否則有效位置)時,typechecker提高執行下列操作之一:
非法使用協變類型的參數(輸入[4120])...
as
個約束是逆變非法使用逆變型參數的(打字[4121])...
super
約束是協變
參照上實施該約束的右側的參數。
我可以更明白爲什麼泛型方法會造成問題。違規的位置相當明顯,並且使用的參數匹配他們的約束方差位置是不可能的:
class A<+TCov, -TCon> {
public function cov_violate<T as TCov>(T $v): void {
// T can be cast to TCov and violate type if the original type is a subtype of T
}
public function con_violate<T super TCon>(): T {
// vice versa for the contravariant parameter
}
public function cov_impossible<T as TCov>(): T {
// how will we produce a T-typed value?
}
public function con_impossible<T super TCov>(T $v): void {
// what will we do with a T-typed value?
}
}
但是,什麼是類範圍的參數問題?對於所有六種錯誤關係({+|-| }T as +TCov
和{+|-| }T super -TCon
),我無法想象這些類型不安全的情況。在我看來,他們的差異似乎要麼足以限制他們的投射方向或他們的位置,以便讓這些關係安全。