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 类型参数的界定

trait Similar {   def isSimilar(x: Any): Boolean } case class MyInt(x: Int) extends Similar {   def ...
  • fenghuangdesire
  • fenghuangdesire
  • 2015年03月04日 10:44
  • 1443

PHP 界定符(<<<),单双引号

之前都没有看见过界定符,今天正好书上看见,感觉比较好奇,百度了一下,以下是结合单双引号的一些比较 三者双引号(“”),单引号(‘’),界定符( (1)单引号 单引号是不做内容解析的,即原样输出,...
  • pan_xi_yi
  • pan_xi_yi
  • 2015年05月12日 17:04
  • 1216

php关于<<< 界定符 的用法

【目前已经学到php了,昨天配置了一下php的开发环境,各种小问题都已经得到解决】 source: https://zhidao.baidu.com/question/549215119.html ...
  • frankarmstrong
  • frankarmstrong
  • 2017年04月30日 11:00
  • 888

数据链路层(四)

1:点对点信道:一对一的点对点通信方式。 2:数据链路:除了物理层外,还有一些必要的通信协议。 封装成帧,透明传输,差错检测。       A -------------------B...
  • MsStrbig
  • MsStrbig
  • 2017年10月23日 20:15
  • 91

Python正则表达式--前向界定符

前向界定符包括前向肯定界定符和前项否定界定符,如下所示: (?=...) 前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引...
  • lwnylslwnyls
  • lwnylslwnyls
  • 2013年05月08日 17:48
  • 1754

scala类型系统:13) context bounds-上下文界定

scala类型系统:13) context bounds context bounds-上下文界定 与view bounds一样context bounds(上下文界定)也是隐式参数的语法糖。co...
  • jiangpeng59
  • jiangpeng59
  • 2016年11月09日 09:52
  • 487

第62讲:Scala中上下文界定内幕中的隐式参数与隐式参数的实战详解及其在Spark中的应用源码解析学习笔记

第62讲:Scala中上下文界定内幕中的隐式参数与隐式参数的实战详解及其在Spark中的应用源码解析学习笔记 本讲通过隐式参数和隐式转换的角度讲解上下文界定。 class Pair_Implici...
  • slq1023
  • slq1023
  • 2015年09月30日 21:27
  • 552

scala进阶4-上下文界定(Context)

/** * "[T: Ordering]" 上下文界定 */ class Pair_Ordering[T: Ordering](val first: T, val second: T) { ...
  • dingyuanpu
  • dingyuanpu
  • 2016年08月10日 00:52
  • 1079

scala进阶2-类型变量界定Bounds

/** * 类型变量界定Bounds(上界、下界) * "
  • dingyuanpu
  • dingyuanpu
  • 2016年08月08日 23:38
  • 287

正则表达式的前向界定

正则表达式 使用前向界定的字符串长度必须是常数 所以数量词 *  +  {} 是没法用在前向界定中的,唯一的例外是?...
  • yunbugui
  • yunbugui
  • 2016年12月22日 18:35
  • 245
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Scala-类型参数和界定
举报原因:
原因补充:

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