Scala-类型参数和界定

原创 2016年10月05日 10:15:40

1.协变和逆变

下面以队列为例
trait Queue[T]{
	//some trait member....
}
我们知道AnyRef是String的超类,但能否说Queue[String就是Queue[AnyRef]的子类类型呢?从更加广泛的意义上来说,如果S是T的子类型,那么能否把Queue[S]当作Queue[T]的子类类型?
答案是否定的,但是Scala的另一种特效----协变(Covariant)就可以实现上面的功能
trait Queue[+T]{
	//some trait member....
}
与之对应的就是逆变(Contravariant),如果S是T的子类型,这将隐含着Queue[S]是Queue[T]的子类型 (有点奇怪)
trait Queue[-T]{
	//some trait member....
}
下面看下一个具体的例子Cell单元格类,它具有简单的读写操作
class Cell[T] (init:T) {
  private[this] var current=init
  def get=current
  def set(x:T){current=x}
}
下面的操作会报错
val c1=new Cell[String]("abc") //正常
val c2:Cell[AnyRef]=c1 //类型不匹配异常
但是把Cell的声明如下,就不会出现异常了
class Cell[+T] (init:T) {
}
但是上面的类还是存在一些潜在的问题,比如
def main(args: Array[String]) {
    val c1=new Cell[String]("abc") //正常
    val c2:Cell[AnyRef]=c1 //正常
    c2.set(1)   //正常
    val s:String=c1.get //把int类型赋值给了String类型 异常
}
其实上面的操作都是由于下面的语句导致
def set(x:T){current=x}
所有这类问题得多加注意,书上给出了一条经验之谈--“”不允许使用+号注解的类型参数作为方法参数类型”

2.上界

比如下面的列子,Comparable[T]就是T的上界,T是Comparable[T]的子类,它具有compareTo方法,否则使用的时候会报错
class Compare2[T<:Comparable[T]](val first:T,val second:T ){
  def compare=if(first.compareTo(second)>0) 1 else 0
}

3.下界

其中T为R的下界,也就是说R为T的超类。这里new了一个父类型
class LowerBounds[+T](val first:T) {
  def replace[R >: T](newFirst:R)=new LowerBounds[R](newFirst)
}

4.视图界定

视图界定(Views Bounds),其符号为 T <% S,其和上界类似。以下面的代码为例,Int类型是没有继承Ordered类型的,但是因为使用了隐式转换(待分析),它会自动把Int转换成RichInt类型,而RichInt继承了Ordered类型

class Compare3[T<%Ordered[T]](val first:T,val second:T ){
  def compare=if(first>second) 1 else 0
}
val c=new Compare3[Int](2,1); //Int->RichInt

 



 
 



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Scala入门之类型参数

1.泛型泛型用于指定方法或类可以接受任意类型参数,参数在实际使用时才被确定,泛型可以有效地增强程序的适用性,使用泛型可以使得类或方法具有更强的通用性。 在Scala中用方括号来定义类型参数,即用[]表...

Scala学习笔记7 - 类型参数化

===类型参数化       在scala中,类型参数化(类似于泛型)使用方括号实现,如:Foo[A],同时,我们称Foo为高阶类型。如果一个高阶类型有2个类型参数,则在声明变量类型时可以使用中缀形式...

Scala入门到精通——第十七节 类型参数(一)

本节主要内容 类型变量界定(Type Variable Bound) 视图界定(View Bound) 上界(Upper Bound)与下界(Lower Bound) 1. 类型变量界定(Type V...

快学Scala第17章----类型参数

本章要点 类、特质、方法和函数都可以有类型参数 将类型参数放置在名称之后,以方括号括起来。 类型界定的语法为 T : LowerBound、 T ...

Scala入门到精通——第二十节 类型参数(二)

本节主要内容 Ordering与Ordered特质上下文界定(Context Bound)多重界定类型约束 1. Ordering与Ordered特质 在介绍上下文界定之前,我们对Scala...

Scala入门到精通——第二十一节 类型参数(三)-协变与逆变

本节主要内容 协变 逆变 类型通匹符 1. 协变 协变定义形式如:trait List[+T] {} 。当类型S是类型A的子类型时,则List[S]也可以认为是List[A}的子类型,即List[...

【Scala类型系统】隐式转换与隐式参数

隐式转换隐式转换是使用implicit修饰的带有单个参数的普通函数。这种函数将自动应用,将值从一种类型转换为另一种类型。 举例说明: 我们想将整数n转换为分数n/1, 定义implicit...

Scala之类型参数化:Type Parameterization

Scala之类型参数化:Type ParameterizationScala之类型参数化Type Parameterization 型变Variance 不变 Invariant 协变Covarian...

快学Scala读书笔记之Chapter15(注解)、Chapter17(类型参数)

第十五章注解让程序员可以在程序中的各项条目中添加信息。这些信息可以被编译器或外部工具处理。要点 注解是那些可以插入到代码中以便有工具可以对它们进行处理的标签。工具可以在代码级别用作,也可以处理被编译器...

Scala入门到精通——第二十节 类型参数(二)

本节主要内容 上下文界定(Context Bound) 多重界定 类型约束 型变 1. 上下文界定在第十七节中的类型参数(一)中,我们提到视图界定可以跨越类继承层次结构,其后面的原理是隐式转换。本节要...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Scala-类型参数和界定
举报原因:
原因补充:

(最多只允许输入30个字)