Унификация и неявное приведение параметра типа

class Base и class Ext extends Base. class B<T> с типизированным методом foo<T>(value:T)

Почему B<Base>.foo не принимает экземпляр B<Ext> (неявное понижение параметра типа?) по умолчанию?

Вот пример: http://try.haxe.org/#d443f

class Test {
    static function main() {

        var bExt = new B(new Ext());
        var bBase = new B(new Base());

        bBase.foo(bExt);
        //ofc 
        //bBase.foo(cast bExt);
    }
}

class B<T>
{
   public function new(v:T)
   {
   }

   public function foo(v:B<T>)
   {
      //  
   }
}

class Base {
    public function new(){}
}
class Ext extends Base {
    public function new(){
        super();
    }
}

Есть ли способ вызвать неявное приведение параметра типа для B.foo?


person Mihail Ignatiev    schedule 26.10.2015    source источник
comment
Разве руководство Haxe по дисперсии не описывает именно эту проблему?   -  person D-side    schedule 26.10.2015
comment
Да, да, это так, глупый я.   -  person Mihail Ignatiev    schedule 26.10.2015
comment
нет смысла в самокритике, это был актуальный вопрос .-. Рад, что был полезен.   -  person D-side    schedule 26.10.2015


Ответы (1)


Есть три варианта интерпретации и ответа на ваш вопрос:

1. foo(v:B<T>):

Это ваш пример, и он не компилируется, поскольку T не может быть вариантом. Это происходит из-за самого существования foo и потому, что разрешение bBase.foo(bExt), то есть объединение bExt с bBase, позволит затем bBaseOfbExt.foo(bBase).

Тот факт, что foo существует и потенциально может изменить тип, делает bExt объединение с bBase небезопасным; вы можете увидеть похожее (но, возможно, более ясное) объяснение в руководстве по использованию массивов: система типов отклонение.

2. foo(v:T):

Это ближе к тексту вашего вопроса (но не в примере) и работает хорошо .

3. foo<A>(v:B<A>):

Наконец, если у вас есть параметризованный тип метода, он также работает, но вы, вероятно, столкнетесь с другой дисперсией. вопросы в другом месте.

person Jonas Malaco    schedule 26.10.2015