scala 学习笔记(八)

函数和闭包

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

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

1.方法

带私有的 processLine 方法的 LongLines 对象 

import scala.io.Source
object 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 里,另一个改善变为可能了。请注意 filename width是怎样不改变地传入到帮助函数中。这不是必须的,因为本地函数可以访问包含它们的函数的参数。你可以直接使用外部 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 + 1
increase: (Int) => Int = <function>
scala> increase(10)
res0: Int = 11

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

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 + c
sum: (Int,Int,Int)Int
scala> val f = (_: Int) + (_: Int)
f: (Int, Int) => Int = <function>
scala> f(5, 10)
res11: Int = 15


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值