文档章节

快学Scala 第17章 - 类型参数 习题解答

圣洁之子
 圣洁之子
发布于 2015/04/28 07:11
字数 1189
阅读 446
收藏 2

1. 定义一个不可变类Pair[T,S],带一个swap方法,返回组件交换过位置的新对偶。

package ex17_01
object Main extends App {
  val p = new Pair(97 -> 'a')
  val a = p.swap
  println(a)
}
class Pair[T, S](val p: (T, S)) {
  def swap = {
    (p._2, p._1)
  }
}
/*output:
(a,97)
*/

 

2. 定义一个可变类Pair[T],带一个swap方法,交换对偶中组件的位置。

package ex17_02
object Main extends App {
  val p = new Pair(97 -> 'a')
  println(p.swap)  
  p.p = 98 -> 'b'
  println(p.swap)
}
class Pair[T](var p: (T, T)) {
  def swap = {
    (p._2, p._1)
  }
}
/*output:
(a,97)
(b,98)
*/

 

3.  给定类Pair[T,S],编写一个泛型方法swap,接受对偶作为参数并返回组件交换过位置的新对偶。

package ex17_03
object Main extends App {
  val p = new Pair
  println( p.swap( 97 -> 'a' ) )
}
class Pair[T, S] {
  def swap[T, S](p: (T, S)) = {
    (p._2, p._1)
  }
}
/*output:
(a,97)
*/

 

4. 在17.3节中,如果我们想把Pair[Person]的第一个组件替换成Student,为什么不需要给replaceFirst方法定一个下界?

回答:因为Student是Pair的子类(型),所以不需要给replaceFirst方法定一个下界即可把Pair[Person]的第一个组件替换成Student。

package ex17_04
object Main extends App {
  val p1 = new Person
  val p2 = new Person
  val s1 = new Student
  val pair = new Pair(p1, p2)
  pair.replaceFirst(s1) //返回值类型为  Pair[Person]
}
class Pair[T](val first: T, val second: T) {
  def replaceFirst(newFirst: T) = new Pair[T](newFirst, second)
}
class Person
class Student extends Person
/*output:
(a,97)
*/

 

5.  为什么RichInt实现的是 Comparable[Int]而不是Comparable[RichInt]?

回答:RichInt是Int的富包装类,提供了很多便捷方法,其目的不是为了取代Int而是增强Int。

而接口 Comparable 位于 java.lang包。实现  Comparable[Int] 比 实现 Comparable[RichInt] 通用得多。

package ex17_05
import scala.runtime.RichInt
object Main extends App {
  val a = new RichInt(1)
  val b = new RichInt(2)
  val c = 3
  //println ( a max b) //type mismatch; found : scala.runtime.RichInt required: Int
  println ( a max c)
}
/*output:
3
*/

6. 编写一个泛型方法middle,返回任何Iterable[T]的中间元素。举例来说,middle["World"]应得到'r'。

package ex17_06
object Main extends App {
  def middle[T](it: Iterable[T]): T = {
    def list = it.toList
    list(list.size / 2)
  }
  val str = "World"
  println("%s's middle is %c".format(str, middle(str)))
}
/*output:
World's middle is r
*/

7. 查看Iterable[+A]特质。哪些方法使用了类型参数A?为什么在这些方法中类型参数位于协变点?

解答:foldLeft, foldRight, groupBy 等方法使用了类型参数A。因为在函数参数中,型变是反转过来的——它的参数是协变的。

8. 在17.10节中,replaceFirst方法带有一个类型界定。为什么你不能对可变的Pair[T]定义一个等效的方法?

def replaceFirst[R >: T](newFirst : R) { first = newFirst)  //错误

回答:首先,newFirst无法赋值给first。因为first是T类型,而newFirst是R类型,而T是R的子类型而非亲类型。

其次,可变的Pair[T],会导致下述编译错误:

covariant type T occurs in contravariant position in type T of value first_=

covariant type T occurs in contravariant position in type T of value second_=  

完整代码:

package ex17_08
object Main extends App {
}
//covariant type T occurs in contravariant position in type T of value first_=
//covariant type T occurs in contravariant position in type T of value second_=
//class Pair[+T](val first: T, val second: T) { //ERROR
class Pair[T](var first: T, var second: T) { 
  //type mismatch; found : newFirst.type (with underlying type R) required: T
  //def repalceFirst[R >: T](newFirst: R) { first = newFirst } //ERROR
}

9. 在一个不可变类Pair[+T]中限制方法参数看上去可能有些奇怪。不过,先假定你可以在Pair[+T]中定义

def replaceFirst(newFirst : T)

问题在于,该方法可能会被重写(以某种不可靠的方式)。构造出这样的一个示例。

定义一个Pair[Double]的子类NastyDoublePair,重写replaceFirst方法,用newFirst的平方根开做新对偶。

然后对实际类型为 NastyDoublePair的 Pair[Any]调用 replaceFirst("Hello")。

解答:

// 假定可以不用限制方法参数,那么对实际类型为NastyDoublePair的Pair[Any]调用replace("Hello")时,

// 调用的是NastyDoublePair中重写了的replaceFirst,而其要求的是Double,所以会出错:type mismatch。

package ex17_09
object Main extends App {
}
class Pair[+T](val first: T, val second: T) {
  //covariant type T occurs in contravariant position in type T of value newFirst
  //def replaceFirst(newFirst: T) = {null} // ERROR
  def replaceFirst[R >: T](newFirst: R) = new Pair[R](newFirst, second)
}
class NastyDoublePair[Double](override val first: Double, override val second: Double) extends Pair[Double](first, second) {
  //type mismatch; found : Double(in class NastyDoublePair) required: scala.Double
  //override def replaceFirst(newFirst: Double) = new Pair(math.sqrt(newFirst), second) //ERROR
}

10. 给定可变类Pair[S, T],使用类型约束定义一个swap方法,当类型参数相同时可以被调用。

回答:

package ex17_10
object Main extends App {
  val a = new Pair(2, 4)
  println(a)
  val b = new Pair("Hi", 1)
  println(b)
}
class Pair[S, T](private var first: S, private var second: T) {
  def swap(implicit ev1: S =:= T, ev2: T =:= S) { // 这里需要双重的 类型约束
    val temp = first
    first = second
    second = temp
  }
  override def toString() = "(" + first +", " + second + ")"
}
/*output:
(2, 4)
(Hi, 1)
 */



© 著作权归作者所有

圣洁之子
粉丝 10
博文 400
码字总数 123571
作品 0
深圳
后端工程师
私信 提问
快学Scala 第18章 高级类型 习题解答

实现一个Bug类,对沿着水平线爬行的虫子建模。move方法向当前方向移动,turn方法让虫子转身,show方法打印出当前的位置。让这些方法可以被串接调用。例如: bugsy.move(4).show().move(6).s...

圣洁之子
2015/05/04
513
1
《机器学习》(周志华)课后习题参考答案

目录: 周志华《机器学习》课后习题解答系列(二):Ch1 - 绪论 周志华《机器学习》课后习题解答系列(三):Ch2 - 模型评估与选择 周志华《机器学习》课后习题解答系列(四):Ch3 - 线性模...

kchai31
2018/01/04
0
0
《软件性能测试与LoadRunner实战教程》新书上市

作者前三本书《软件性能测试与LoadRunner实战》、《精通软件性能测试与LoadRunner实战》和《精通软件性能测试与LoadRunner最佳实战》面市后,受到广大软件测试和开发人员的关注与好评。鉴于很...

fish_yy
2014/11/14
0
0
快学Scala 第16章 XML处理 习题解答

<fred/>(0) 得到什么?<fred/>(0)(0)呢?为什么? 回答:<fred/>(0) 得到一个scala.xml.Node,<fred/>(0)(0)也是得到scala.xml.Node。 因为scala.xml.Node 实现了方法 def apply(i: Int): N......

圣洁之子
2015/04/26
900
0
《Oracle数据库基础与应用教程》一本Oracle入门教材

《Oracle数据库基础与应用教程》书全面讲述了Oracle数据库的日常管理工作内容。全书共14章,包含Oracle简介和安装、Oracle客户端、管理Oracle环境、Oracle体系结构、管理Oracle存储结构、SQL...

airfish2000
2016/08/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OpenStack 简介和几种安装方式总结

OpenStack :是一个由NASA和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。项目目标是提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台。OpenSta...

小海bug
昨天
5
0
DDD(五)

1、引言 之前学习了解了DDD中实体这一概念,那么接下来需要了解的就是值对象、唯一标识。值对象,值就是数字1、2、3,字符串“1”,“2”,“3”,值时对象的特征,对象是一个事物的具体描述...

MrYuZixian
昨天
6
0
数据库中间件MyCat

什么是MyCat? 查看官网的介绍是这样说的 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务、ACID、可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵...

沉浮_
昨天
6
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
昨天
7
0
常用物流快递单号查询接口种类及对接方法

目前快递查询接口有两种方式可以对接,一是和顺丰、圆通、中通、天天、韵达、德邦这些快递公司一一对接接口,二是和快递鸟这样第三方集成接口一次性对接多家常用快递。第一种耗费时间长,但是...

程序的小猿
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部