如何实现Scala的above,beside和toString

接下来一步,我们将在类Element中实现方法above。把一个元素放在另一个上面是指串连这两个元素的contents值。因此方法above的***个草案看上去可能是这样的:

岐山网站建设公司成都创新互联,岐山网站设计制作,有大型网站制作公司丰富经验。已为岐山上千余家提供企业网站建设服务。企业网站搭建\外贸网站制作要多少钱,请找那个售后服务好的岐山做网站的公司定做!

 
 
 
  1. def above(that: Element): Element =
  2.  new ArrayElement(this.contents ++ that.contents)

++操作符串连两个数组。Scala里的数组被表示为Java数组,但是支持更多的方法。特别是,Scala里的数组继承自类scala.Seq,能够表现象序列这样的结构并包含许多访问和转换序列的方法。本章会解释某些数组方法,更全面的讨论将在第17章。

编辑推荐:Scala编程语言专题

实际上,前面展示的代码并不完全足够,因为它不允许你把不同长度的元素堆叠在一起。然而本节为了让事情保持简单,我们会任由其状态并仅仅把相同长度的元素传递给above。10.14节里,我们会给above做个改良,这样客户就能用它组合不同长度的元素了。

下一个要实现的方法是beside。把两个元素靠在一起,我们将创造一个新的元素,其中的每一行都来自于两个元素的相应行的串连。如前所述,为了保持事情简单我们会一开始假设两个元素高度相同。这产生了方法beside的下列设计:

 
 
 
  1. def beside(that: Element): Element = {
  2.  val contents = new Array[String](this.contents.length)
  3.  for (i < - 0 until this.contents.length)
  4.   contents(i) = this.contents(i) + that.contents(i)
  5.  new ArrayElement(contents)
  6. }

beside方法首先分配了一个新数组,contents,并串连this.contents和that.contents中相应的数组元素来填充。最终产生了新的ArrayElement包含了新的contents。

尽管beside的这个实现可以工作,但它是指令式风格,马脚露在我们索引数组的循环。这个方法可以替代缩减成一个表达式:

 
 
 
  1. new ArrayElement(
  2.  for (
  3.   (line1, line2) < - this.contents zip that.contents
  4. ) yield line1 + line2
  5. )

这里,this.contents和that.contents两个数组被使用zip操作符转换为一个对子的数组(可以称为Tupele2)。zip方法从它的两个参数中拣出相应的元素并组织成对子数组。

例如,表达式:

 
 
 
  1. Array(1, 2, 3) zip Array("a", "b")

将生成:

 
 
 
  1. Array((1, "a"), (2, "b"))

如果两个操作数组的其中一个比另一个长,zip将舍弃余下的元素。在上面的表达式中,左操作数的第三个元素,3,没有组成结果的部分,因为它在右操作数中没有相对的元素。

结果数组然后通过for表达式被枚举遍历。这里,表达式“for ((line1, line2) < - ...”允许你在一个模式:pattern中命名对子的两个元素,也就是说,line1现在代表对子的***个元素,line2代表第二个。Scala的模式匹配系统将在第15章描述。现在,你可以就把这当作在每次枚举中定义两个val,line1和line2的方式。

for表达式有个yield部分能产生结果。结果与枚举遍历的表达式类型一致,也就是说,是数组。数组的每个元素都是相应行,line1和line2串连的结果。因此这段代码的最终结果与前一个版本的beside一样,不过因为它避免了显示的数组索引,结果用一种更少犯错的方式实现了。

你还需要一个显示元素的方式。通常,可以通过定义toString方法返回元素格式化成的字串做到。下面是它的定义:

 
 
 
  1. override def toString = contents mkString "\n"

toString的实现使用了mkString,它被定义在所有序列中,包括数组。正如你在7.8节中看到的,像“arr mkString sep”这样的表达式能返回数组arr所有元素组成的字串。通过调用toString方法每个元素被映射为字串。分隔符字串seq被插入到连续的元素字串当中。因此表达式“contents mkstring "\n"”格式化contents数组为字串,其中每个数组元素占据一行。

请注意toString没有带空参数列表。这个遵循了统一访问原则的建议,因为toString是一个纯的不带任何参数的方法。

附加了这三个方法,类Element现在看上去如代码10.9所展示的。

 
 
 
  1. abstract class Element {
  2.  def contents: Array[String]
  3.  def width: Int =
  4.   if (height == 0) 0 else contents(0).length
  5.  def height: Int = contents.length
  6.  def above(that: Element): Element =
  7.   new ArrayElement(this.contents ++ that.contents)
  8.  def beside(that: Element): Element =
  9.   new ArrayElement(
  10.    for (
  11.     (line1, line2) < - this.contents zip that.contents
  12.    ) yield line1 + line2
  13.   )
  14.  override def toString = contents mkString "\n"
  15. }

代码 10.9 带有above,beside和toString的类Element

【相关阅读】

  1. Scala学习:使用组合与继承
  2. 在Scala中定义final成员
  3. Scala程序中如何实现多态和动态绑定
  4. Scala学习:调用超类构造器和override修饰符的使用
  5. Scala:重载方法和字段及定义参数化字段

分享标题:如何实现Scala的above,beside和toString
当前路径:http://www.hantingmc.com/qtweb/news19/153869.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联