scala 学习笔记(八)

来源:互联网 发布:藏文翻译软件 编辑:程序博客网 时间:2024/04/28 08:19

函数和闭包

当程序变得庞大时,你需要一些方法把它们分割成更小的,更易管理的片段。为了分割控制流,Scala提供了所有有经验的程序员都熟悉的方式:把代码分割成函数。 

实际上,Scala提供了许多Java中没有的定义函数的方式。除了作为对象成员函数的方法之外,还有内嵌在函数中的函数,函数文本和函数值。本章带你体会所有Scala 中的这些函数的风味。 

1.方法

带私有的 processLine方法的 LongLines对象 

import scala.io.Sourceobject LongLines {  def processFile(filename: String, width: Int) {   val source = Source.fromFile(filename)   for (line <- source.getLines)     processLine(filename, width, line)  }  private def processLine(filename:String, width:Int, line:String) {   if (line.length > width)     println(filename+": "+line.trim)  }}

2.本地函数

上节中 processFile方法的建立演示了函数式编程风格的一个重要设计原则:程序应该被解构成若干小的函数,每个完成一个定义良好的任务。 

Java 里,达成这个目的的主要工具是private 方法。这种私有方法的方式在 Scala里同样有效,如代码 8.1 里描述的,但是Scala 提供了另一种方式:你可以把函数定义在另一个函数中。就好象本地变量那样,这种本地函数仅在包含它的代码块中可见。以下是一个例子: 

def processFile(filename: String, width: Int) {  def processLine(filename:String, width:Int, line:String) {    if (line.length > width) 
      print(filename+": "+line)  }  val source = Source.fromFile(filename)  for (line <- source.getLines) {    processLine(filename, width, line)  }}

在这个例子中,我们通过把私有方法,processLine,转换为本地方法,processFile ,既然 processLine被定义在 processFile里,另一个改善变为可能了。请注意 filenamewidth是怎样不改变地传入到帮助函数中。这不是必须的,因为本地函数可以访问包含它们的函数的参数。你可以直接使用外部processLine 函数的参数 。

3.函数式第一类值

Scala 拥有第一类函数:first-class function。你不仅可以定义函数和调用它们,还可以把函数写成没有名字的文本:literal并把它们像值:value那样传递。函数文本被编译进一个类,类在运行期实例化的时候是一个函数值:function value。 

以下是对数执行递增操作的函数文本的简单例子:

(x: Int) => x +1

=>指明这个函数把左边的东西(任何整数x)转变成右边的东西(x + 1)。所以,这是一个把任何整数x映射为x + 1的函数。 

函数值是对象,所以如果你愿意可以把它们存入变量。它们也是函数,所以你可以使用通常的括号函数调用写法调用它们。以下是这两种动作的例子:

scala> var increase = (x: Int) => x + 1increase: (Int) => Int = <function>scala> increase(10)res0: Int = 11

本例中,因为 increasevar,你可以在之后重新赋给它不同的函数值。 

scala> increase = (x: Int) => x + 9999

集合类型还有 filter方法 

scala> someNumbers.filter((x: Int) => x > 0)res6: List[Int] = List(5, 10)

4.函数文本短格式

scala> someNumbers.filter((x) => x > 0)res7: List[Int] = List(5, 10)

5.占位符语法

如果想让函数文本更简洁,可以把下划线当做一个或更多参数的占位符,只要每个参数在函数文

本内仅出现一次。比如,_ > 0对于检查值是否大于零的函数来说就是非常短的标注: 

scala> someNumbers.filter(_ > 0)res9: List[Int] = List(5, 10)
scala> def sum(a: Int, b: Int, c: Int) = a + b + csum: (Int,Int,Int)Int
scala> val f = (_: Int) + (_: Int)f: (Int, Int) => Int = <function>scala> f(5, 10)res11: Int = 15


0 0
原创粉丝点击