代码之家  ›  专栏  ›  技术社区  ›  Julian

内联时缺少编译/运行时错误

  •  1
  • Julian  · 技术社区  · 14 年前

    我在Scala有以下几个类/特点

    trait Write[-T] {
        def add(elem : T);
    }
    
    class ContraListWrapper[T] (var list : List[T]) extends Write[T]  {
      def add(elem : T) = { 
        list = elem :: list
      }
    }
    
    def bar(list : Write[Number]) = {}
    

    var list : List[Number] = Nil;
    var wlist = new ContraListWrapper(list);
    bar(wlist);
    
    var list : List[Object] = Nil;
    var wlist = new ContraListWrapper(list);
    bar(wlist);
    

    var list : List[Integer ] = new Integer(1) :: Nil;
    var wlist = new ContraListWrapper(list);
    bar(wlist); //error: type mismatch; 
    //found   : contra.this.ContraListWrapper[Integer] 
    //required: contra.this.Write[Number]
    

    但是,当我内联一个整数列表的变量声明时,编译错误就消失了,它甚至看起来还能工作。(我可以在方法的列表中添加元素 )

    var list : List[Integer] = new Integer(1) :: Nil;
    bar(new ContraListWrapper(list)); //no compile- nor runtime error 
    

    编辑:回答thx对Rex Kerr的提问

    选择第一个类型Integer,带有内联编号

    Scala可以采用适当的类型

    3) 为什么我不会得到一个运行时错误? 因为列表是协变的

    1 回复  |  直到 14 年前
        1
  •  3
  •   Rex Kerr    14 年前

    List 是协变的,所以 List[Number] List[Integer] . 在第二种情况下,Scala查看代码并说,“嗯,bar想要键入带有数字的内容,所以让我们看看是否可以 ContraListWrapper 把它还给我。当然,我们可以——我们可以告诉它,它越来越大了 列表[整数] ."

    在第一种情况下,类型已经固定。

    bar(new ContraListWrapper[Integer](list));
    

    这会产生一个编译时错误,因为编译器不能随意选择类型 Number .