美文网首页
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泛型

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

  • Scala泛型

    泛型的意思是 泛指某种具体的数据类型 , 在Scala中, 泛型用 [数据类型] 表示. 在实际开发中, 泛...

  • Scala 泛型以及泛型约束

    泛型类 在类声明时,定义一些泛型类型,然后在类的内部,就可以使用这些泛型类型 在需要对类中的某些成员,如字段或方法...

  • Scala 类型系统

    1.在scala泛型中获取其 Class[T] 需求:获取一个泛型 T 的 class 类型的 Class[T],...

  • scala 泛型类型

    使用泛型类,通常是需要对类中的某些成员,比如某些field和method中的参数或变量,进行统一的类型限制,这样可...

  • 好程序员大数据培训分享Scala系列之泛型

    好程序员大数据培训分享Scala系列之泛型,带有一个或多个类型参数的类是泛型的。 泛型类的定义: //带有类型参数...

  • [译]Scala泛型类

    泛型类是以一个类型作为参数的类。对于集合类特别有用。 定义泛型类 泛型类以一个类型作为参数,包含在[]中。试用字母...

  • Scala 泛型协变与泛型边界

    代码准备 泛型协变 泛型协变、逆变、不变是指拥有泛型的类在声明和赋值时的对应关系。 协变:声明时泛型是父类,赋值时...

  • Spark(七):scala类型系统编程实战

    一、泛型的操作 背景scala的类和方法1、函数都可以是泛型,在Spark源码中可以到处看到类和方法的类型,在实际...

  • Scala 通俗易懂 ---- 协变、逆变、不变

    协变、逆变、不变 Scala 语言中协变、逆变、不变是指拥有泛型的类型,在声明和赋值时的对应关系 协变:声明时泛型...

网友评论

      本文标题:Scala泛型

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