×
Scala 教程Scala 简介Scala 安装及环境配置Scala 起步Scala 进一步Scala 基础语法Scala 数据类型Scala 变量Scala 访问修饰符Scala 运算符Scala IF...ELSE 语句Scala 循环Scala 函数Scala 闭包Scala 字符串Scala 数组Scala Collection(集合)Scala Match 表达式Scala Iterator(迭代器)没有“break”和“continue”Scala 类和对象Scala Trait(特征)Scala Trait 的基本概念选择瘦接口还是胖接口设计?Scala Trait 示例–RectangularScala Ordered TraitTrait 用来实现可叠加修改操作Scala 模式匹配Scala 正则表达式Scala 异常处理Scala 提取器(Extractor)Scala 文件 I/OScala 减低代码重复Scala 柯里化函数Scala 创建新的控制结构Scala 传名参数Scala 的类层次关系Scala 基本数据类型的实现方法Scala 底层类型

Scala 创建新的控制结构


创建新的控制结构

对于支持函数作为“头等公民”的语言,你可以有效的创建新的控制结构即使该语言语法上固定的。你所要做的事创建一个方法,该方法使用函数类型作为参数。

比如: 下面为一个“双倍”的控制结构,这个“双倍”控制结构可以重复一个操作,然后返回结果。

scala> def twice (op:Double => Double, x:Double) =op(op(x))
twice: (op: Double => Double, x: Double)Double
scala> twice(_ + 1, 5)
res0: Double = 7.0

上面调用 twice ,其中 _+1 调用两次,也就是 5 调用两次 +1,结果为 7。

你在写代码时,如果发现某些操作需要重复多次,你就可以试着将这个重复操作写成新的控制结构,在前面我们定义过一个 filesMatching 函数

def filesMatching(
    matcher: (String) => Boolean) = {
    for(file <- filesHere; if matcher(file.getName))
      yield file
   }

如果我们把这个函数进一步通用化,可以定义一个通用操作如下:

打开一个资源,然后对资源进行处理,最后释放资源,你可以为这个“模式”定义一个通用的控制结构如下:

def withPrintWriter (file: File, op: PrintWriter => Unit) {
  val writer=new PrintWriter(file)
  try{
    op(writer)
  }finally{
    writer.close()
  }
}

使用上面定义,我们使用如下调用:

withPrintWriter(
   new File("date.txt"),
   writer => writer.println(new java.util.Date)
)

使用这个方法的优点在于 withPrintWriter,而不是用户定义的代码,withPrintWriter 可以保证文件在使用完成后被关闭,也就是不可能发生忘记关闭文件的事件。这种技术成为“租赁模式”,这是因为这种类型的控制结构,比如 withPrintWriter 将一个 PrintWriter 对象“租”给 op 操作,当这个 op 操作完成后,它通知不再需要租用的资源,在 finally 中可以保证资源被释放,而无论 op 是否出现异常。

这里调用语法还是使用函数通常的调用方法,使用()来列出参数,在 Scala 中如果你调用函数只有一个参数,你可以使用{}来替代().比如下面两种语法是等价的:

scala> println ("Hello,World")
Hello,World
scala> println { "Hello,world" }
Hello,world

上面第二种用法,使用{}替代了(),但这只适用在使用一个参数的调用情况。 前面定义 withPrintWriter 函数使用了两个参数,因此不能使用{}来替代(),但如果我们使用柯里化重新定义下这个函数如下:

import scala.io._
import java.io._
def withPrintWriter (file: File)( op: PrintWriter => Unit) {
  val writer=new PrintWriter(file)
  try{
    op(writer)
  }finally{
    writer.close()
  }
}

将一个参数列表,变成两个参数列表,每个列表含一个参数,这样我们就可以使用如下语法来调用

withPrintWriter 
val file = new File("date.txt")
withPrintWriter(file){
  writer => writer.println(new java.util.Date)
}

第一个参数我们还是使用()(我们也可以使用{}),第二个参数我们使用{}来替代(),这样修改过的代码使得 withPrintWriter 看起来和 Scala 内置的控制结构语法一样。


分类导航

关注微信下载离线手册

bootwiki移动版 bootwiki
(群号:472910771)