`
edge
  • 浏览: 66788 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Scala概述(五)抽象(1.3、1.4)

阅读更多

二元操作和参数下界(Binary methods and lower bounds迄今为止,我们一直将协变性与不可变数据结构联系在一起,然而由于二元操作(Binary methods,就是指一个对象的方法,其参数类型也是这个对象类型,例如:x+y这种——译注)的存在,这种做法并不完全正确。例如,为GenList类增加一个prepend(前追加)方法,最自然的做法是将其定义成为接收一个相应的list元素类型参数:

abstract class GenList[+T] { ...

def prepend(x: T): GenList[T] = // illegal!

new Cons(x, this)

}

可惜这样做会导致类型错误因为这种定义使得TGenList中处于逆协变的位置从而不能标记为协变参数(+T)。这一点非常遗憾,因为从概念上说不可变的list对于其元素类型而言应该是协变的,不过这个问题可以通过参数下界对prepend方法进行泛化而解决:

abstract class GenList[+T] { ...

def prepend[S >: T](x: S): GenList[S] = // OK

new Cons(x, this)

}

这里prepend是一个多态方法,接收T的某个父类型S作为参数,返回元素类型为Slist。这个定义是合法的,因为参数下界被归类为协变位置,从而TGenList中只出现在协变位置上。

与通配符模式相比较(Comparison with wildcardsJava 5.0中可以提供一种通过通配符标记协变性的方法[45],这种模式本质上是IgarashiViroli提出的可变类型参数[26]的一种语法变体。与Scala不同的是,Java 5.0的标注是针对类型表达式而不是类型定义。例如:在每一个需要用到协变的generic list的时候,都将其声明为GenList<? extends T>,这是一个类型表达式,表示其所声明的对象实例的所有元素都是T的子类型。

协变通配符可以用于任何类型表达式当中,但是要注意,出现在非协变的位置上的类型成员将会被忽略(forgotten),这对于保证类型的正确性是必须的。例如:GenCell<? extends Number>类型只有那个get方法(返回Number类型)才有效,而其set方法,由于其类型参数是逆协变的,会被忽略。

Scala的早期版本中,我们也实验过在调用时标注协变性的方式,类似于通配符。初看之下,这种方式有很大的灵活性,因为一个类型的成员既可以是协变的,也可以是非协变的,用户可以根据情况选择是不是使用通配符。但是,这种灵活性也是有代价的,因为这样作要有用户而不是设计者来保证对协变性的使用是一致的。在实践中我们发现,调用时标注协变性的方式很难保证一致性,经常会出现类型错误。相反,定义时标注协变性对于正确地设计类型有很大帮助,例如可以很好地指导人们设计方法时知道哪些应当使用参数下界。另外,Scalamixin构成(见第六节)可以让人很容易将一个类分成协变的和非协变的部分,而在Java这种单根结构+接口的继承模型中,这样做是非常麻烦的。因此,Scala的新版本将标注协变性的方式从使用时标注改为了定义时标注。

分享到:
评论

相关推荐

    Intellij的scala插件1.4

    scala-intellij-bin-1.4.zip,Intellij的scala插件,虽然可以直接在工具里下载,但是特别慢。

    Scala 概述(瑞士洛桑联邦理工)

    Scala 概述(瑞士洛桑联邦理工) Scala 概述(瑞士洛桑联邦理工)

    apollo-scala-1.3-scaladoc.jar

    标签:apollo-scala-1.3-scaladoc.jar,apollo,scala,1.3,scaladoc,jar包下载,依赖包

    apollo-scala-1.4-scaladoc.jar

    标签:apollo-scala-1.4-scaladoc.jar,apollo,scala,1.4,scaladoc,jar包下载,依赖包

    Algebird—Scala的抽象代数工具

    Algebird —Scala的抽象代数工具

    scala五本经典资料集合

    scala是一个经典的语言,Scala代表了一个新的语言品种,它抹平了这些人为划分的界限。但是现在scala的相关学习资料不多,因此,本人总结了几篇写的较好的scala学习资料,包含&lt;ScalaQuery_Commerzbank_2011&gt;&lt;twitter-...

    scala课件.zip

    Scala概述.pptx 变量.pptx 运算符.pptx 程序流程控制.pptx 函数式编程基础.pptx 面向对象编程(基础部分).pptx 面向对象编程(中级部分).pptx 面向对象编程(高级特性).pptx 隐式转换和隐式参数.pptx 集合(上)-基本使用...

    awaitility-scala-1.3.jar

    官方版本,亲测可用

    awaitility-scala-1.3-sources.jar

    官方版本,亲测可用

    Scala程序设计(第2版)

    1.3 使用Scala 8 1.4 并发 17 1.5 本章回顾与下一章提要 27 第2章 更简洁,更强大 28 2.1 分号 28 2.2 变量声明 29 2.3 Range 31 2.4 偏函数 32 2.5 方法声明 33 2.5.1 方法默认值和...

    scala编程中文pdf

    scala编程 33章 中文pdf Scala编程实战 目录 第1章字符串. 11 第2章数值39 第3章控制结构.60 第4章类和属性.103 第5章方法147 第6章对象170 第7章包和导入.190 第8章特质200 第9章函数式编程214 第10 章集合242 第...

    Programming.in.Scala.pdf

    Programming.in.Scala.pdf

    Scala 专题教程 - 抽象成员-内含源码以及设计说明书(可以自己运行复现).zip

    Scala 专题教程 - 抽象成员-内含源码以及设计说明书(可以自己运行复现).zip

    scala sdk scala-2.12.3

    scala-2.12.3 scala-2.12.3 scala-2.12.3 scala-2.12.3

    scala-sbt-scala编译工具

    scala 编译工具 sbt 安装包。 Little or no configuration required for simple projects Scala-based build definition that can use the full flexibility of Scala code Accurate incremental recompilation ...

    Scala编程实战.zip

    此文档是讲解实战Scala,希望对喜欢大数据的同学有所帮助!!! 学习Scala语言,不仅仅意味着熟悉新的API,更重要的是一种思维方式的转变。从原有的面向对象编程(OO)到函数式编程(FP)的思想。本书面向实际的使用场景...

    spark平台scala语言自己实现的kmeans算法,相比于MLlib的Kmeans更简单,更容易看懂,代码量少注释多

    不到一百行的代码教你在spark平台中使用scala实现kmeans算法。简单易懂,大量注释。适合初学者参考理解。本程序在intelliJ IDEA2016.1.1 中编程,运行在spark1.6.1 scala2.10.4本地模式下运行成功。 数据集:(其实...

    Scala函数式编程

    很大篇幅都放在,使用scala实现scala默认库文件的API中,通过对简单的函数式编程逻辑的介绍和实践,主要是实践,建立起来一个比较明晰的scala思维模式,或者叫函数式编程的思维模式。 2 无副作用的函数式编程,同时...

    scala 2.13.3 API 文档 Html离线版 scala-api.rar

    最新制作 scala 2.13.3 API 文档 Html离线版 Scala 是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性。 Scala 运行在 Java 虚拟机上,并兼容现有的 Java 程序。

Global site tag (gtag.js) - Google Analytics