0

タイプチェッカーは、インターフェースによるこのクラス要件をIBase循環的であると見なします。

<?hh // strict
interface IBase {
    require extends Derived;
}
class Derived implements IBase {}
// Cyclic class definition : IBase Derived  (Typing[4013])

implements IBase私が理解しているように、制約はすべての子孫がextends Derived. 私が見ていないこれに穴はありますか?

なぜ私は気にするのですか?

それ自体またはそのサブタイプの他のインスタンスと比較したいインターフェースに興味があります。

<?hh // strict
interface Comparable<-T as Comparable<T>> {
    require extends ArtificialCeiling;
    public function compare(T $comparee): bool;
}
abstract class ArtificialCeiling implements Comparable<ArtificialCeiling> {
    abstract public function compare(ArtificialCeiling $comparee): bool;
}

特にインターフェイスでは、反変の位置では健全ではないthisため、ここでは答えではありません)this

のラッパーを受け入れて保存Comparableしたいが、それがどのタイプを持ち歩いているかは気にしないとComparableします。通常、上限でパラメータ化するmixedか、制約がない場合はパラメータ化します。

問題は、上限ComparableComparable<Comparable<Comparable<...永遠であることですが、それを永遠に入力するスタミナがありません。Scala のような存在型や のような複数の制約がなければTComparable as Comparable & ArtificialCeiling、あまり明白でない方法に頼る必要があります。require extends ArtificialCeilingこれは複数の制約のようなものであり、この不思議な循環問題がなければ、きちんとした修正になります。

もう 1 つの自然な代替方法は、受け入れクラスがパラメーターを として独自のパラメーター リストに追加することTComparable as Comparable<TComparable>ですが、これは を気にしないという原則を無効にしTComparableます。

4

1 に答える 1