美文网首页
Scala泛型

Scala泛型

作者: wangdy12 | 来源:发表于2018-03-17 11:05 被阅读0次

    泛型类是以类型作为参数,Scala类型参数放在方括号[]中,Java放在<>

    变型 Variance

    Scala与Java一样,普通泛型类型都是不变的(invariant)
    Scala支持对泛型类的类型参数添加变化型注释,使得他们是协变的(covariant),逆变的(contravariant)

    • 协变Covariance:AB的子类,List[A]List[B]的子类
    • 逆变Contravariance:对于类class C[-A]AB的子类,C[B]C[A]的子类
    • 不变Invariance:C[B]C[A]没有任何关系
    class C[+A] // A covariant class  
    class C[-A] // A contravariant class
    class C[A]  // An invariant class
    

    trait Function1[-T, +R]的理解
    Scala标准库中Function1代表具有一个参数的函数,参数类型为T,第二个参数类型R 表示返回类型。
    Function1 对它的参数类型来说是逆变,对返回类型来说是协变的(实际上所有函数都是这样的),函数字面量 A => B 表示为 Function1[A, B]

    举例:
    Animal => MouseCat => SmallAnimal的子类型

    abstract class Animal {
      def name: String
    }
    case class Cat(name: String) extends Animal
    case class Dog(name: String) extends Animal
    
    abstract class SmallAnimal extends Animal
    case class Mouse(name: String) extends SmallAnimal
    

    Java数组具有协变性,泛型具有不变型(标准库中List<Object>和List<String>无关)

    //Java代码,可以编译通过,运行抛出异常 java.lang.ArrayStoreException
    Integer[] integer = new Integer[3];
    Object[] objectsArray = integer;
    objectsArray[0] = "dfg";
    System.out.println(objectsArray[0]);
    

    Scala数组类型是不变的,为了与Java数组的兼容,可以进行类型转换,转化为参数类型的任何父类型

    scala> val a1 = Array("abc")
    a1: Array[String] = Array(abc)
    scala> val a2: Array[Object] = a1.asInstanceOf[Array[Object]] //不能直接复制,类型不同
    a2: Array[Object] = Array(abc)
    

    类型边界

    不允许使用+号注解的类型参数作为方法的参数类型,此外由于可变字段var会自动产生setter方法,所以可变字段的类型也不能是协变类型,可以通过函数边界解决这个问题

    //错误的代码
    class Cell[+T](init: T) {
        private[this] var current = init
        def get = current
        def set(x: T) = { current = x } //编译错误 covariant type T occurs in contravariant position in type T of value x
      }
    

    [B <: A] 上界upper bound:表示类型参数B对应类型为A的子类,类似于Java的<? extends A>

    [B >: A] 下界lower bound:表示类型参数或抽象类型B对应类型为A的超类型,通常应用于A为协变类型,设定下界,B作为方法的类型参数

    Java可以通过通配符实现变性
    上界限定<? extends A>,实现了协变性,作为返回类型,或者类型参数
    下界限定<? super A>,实现逆变性,作为输入类型

    术语 Scala Java
    Parametrized type List[String] List<String>
    Actual type parameter String String
    Generic type List<A> List<E>
    Formal type parameter A E
    Unbounded wildcard type List[_] List<?>
    Raw type List List
    Type parameter with lower bound [A >: Number] <E super Number>
    Type parameter with upper bound [A <: Number] <E extends Number>
    Wildcard type with lower bound [_ >: Number] <? super Number>
    Wildcard type with upper bound [_ <: Number] <? extends Number>
    Recursive type bound [A <: Ordered[A]] <T extends Comparable<T>>
    Type constructor List, constructs List[Int] etc Same as in Scala
    Variance annotation + or - i.e. [+A] or [-A] not supported
    Covariance annotation + i.e. [+A] not supported
    Contravariance annotation - i.e. [-A] not supported

    相关文章

      网友评论

          本文标题:Scala泛型

          本文链接:https://www.haomeiwen.com/subject/jpfofftx.html