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

 



 
 



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

相关文章推荐

衡阳火車票预订电话是多少

〓铁道部提供〓订票电话:【θ08-6187-8934-8634】手机用户免费拨打.免费送票上门.(学生).(军人).(残疾人)可享受5-8折优惠订票手续流程:1通过电话订票,票款只能通过银行进行支付不...

scala中yield的使用

1、scala中yield的使用scala> for (i for (i <- 1 to 5) yield i*2 res1: scala.collection.immutable.IndexedS...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

Scala细节-yield格式

yield格式 for表达式每次执行都会产生一个新值(如例子中的arr)。当for表达式完成的时候,结果将包含了所有产生值得对象集合 而yield可以在for中返回我们想要的对象。 注意它的格式,若有...

Scala 的 yield 例子 (for 循环和 yield 的例子)

我看了《Programming in Scala》一书,仍然对 Scala yield 关键字的理解不甚清楚。起初我以为 Scala yield 的与 Ruby 的 yield 是一样,Ruby 中 ...

Scala之旅-提前定义

其实我并不想深入学习它,就如书上说的“The syntax is so ugly that only a mother could love it.”       (O(∩_∩)O哈哈~) 下面是书上...

Java和C#的异同

1.final 关键 a.final修饰类和C#的Sealed 类似都是让类无法继 b.final修饰变量和C#的const(readonly)类似,让其成为常量 c.final修饰方法,因为java...

Scala-偏函数与部分应用函数

scala中有PartialFunction的概念, 同时还要一个概念叫Partial Applied Function. 前者译作偏函数, 后者译作"偏应用函数"或"部分应用函数", 一字之差, 差...

hadoop2.7.0-HA集群部署

1.Linux环境准备 此次使用使用了6台Openstack的Instance(centos6.5)来搭建Hadoop的集群,其中zookeeper来协调分布式管理(通俗:哪台机器若宕了,让另一台上...

Iterator的remove()和Collection的remove()

一、遍历集合的方式有很多,这里就以List 为例 如果是单线程的我们一般使用: int  len= list.size() for (int i=0;i<len;i++){ } 如果是多线程的程序...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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