Scala 闭包

作者: adm 分类: Scala 发布时间: 2024-08-31

在 Scala 中,闭包(Closure)是一种函数,它能够捕获并包含其定义环境中的自由变量。

闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。

闭包可以访问函数外部的变量并在函数内部使用这些变量,即使在变量的作用域已经超出其定义环境时,闭包仍然可以访问这些变量。

闭包的关键在于它可以”关闭”函数外部的变量,使得这些变量在函数内仍然可用。

如下面这段匿名的函数:

val multiplier = (i:Int) => i * 10

函数体内有一个变量 i,它作为函数的一个参数。如下面的另一段代码:

val multiplier = (i:Int) => i * factor

在 multiplier 中有两个变量:i 和 factor。其中的一个 i 是函数的形式参数,在 multiplier 函数被调用时,i 被赋予一个新的值。然而,factor不是形式参数,而是自由变量,考虑下面代码:

var factor = 3
val multiplier = (i:Int) => i * factor

这里我们引入一个自由变量 factor,这个变量定义在函数外面。

这样定义的函数变量 multiplier 成为一个”闭包”,因为它引用到函数外面定义的变量,定义这个函数的过程是将这个自由变量捕获而构成一个封闭的函数。

完整实例
实例
object Test {
def main(args: Array[String]) {
println( “muliplier(1) value = ” + multiplier(1) )
println( “muliplier(2) value = ” + multiplier(2) )
}
var factor = 3
val multiplier = (i:Int) => i * factor
}

运行实例 »

执行以上代码,输出结果为:

$ scalac Test.scala
$ scala Test
muliplier(1) value = 3
muliplier(2) value = 6

以下实例,closure 函数捕获了外部变量 externalVar,当 externalVar 的值改变时,闭包内的计算结果也相应改变。
实例
object ClosureExample1 {
def main(args: Array[String]): Unit = {
var externalVar = 10

val closure = (x: Int) => x + externalVar

println(closure(5)) // 输出 15

externalVar = 20

println(closure(5)) // 输出 25
}
}

执行以上代码,输出结果为:

15
25

闭包作为返回值

以下实例,makeAdder 函数返回一个闭包。不同的闭包实例捕获了不同的 adder 值。
实例
object ClosureExample2 {
def main(args: Array[String]): Unit = {
def makeAdder(adder: Int): Int => Int = {
(x: Int) => x + adder
}

val addFive = makeAdder(5)
val addTen = makeAdder(10)

println(addFive(3)) // 输出 8
println(addTen(3)) // 输出 13
}
}

执行以上代码,输出结果为:

8
13

闭包捕获变量的类型

闭包可以捕获不同类型的变量,包括值类型和引用类型。

以下实例,addMessage 闭包捕获了 messages 变量,并且可以修改它。
实例
object ClosureExample3 {
def main(args: Array[String]): Unit = {
var messages = List(“Hello”, “World”)

val addMessage = (msg: String) => messages = messages :+ msg

addMessage(“Scala”)
println(messages) // 输出 List(Hello, World, Scala)
}
}

执行以上代码,输出结果为:

List(Hello, World, Scala)

闭包与函数式编程

闭包在函数式编程中是一个重要的概念,广泛用于高阶函数、柯里化等技术中。

以下实例,highOrderFunction 函数接受一个函数作为参数。传递的闭包捕获了外部变量 externalVar。
实例
object ClosureExample4 {
def main(args: Array[String]): Unit = {
def highOrderFunction(f: Int => Int, x: Int): Int = f(x)

val externalVar = 5
val closure = (x: Int) => x + externalVar

println(highOrderFunction(closure, 10)) // 输出 15
}
}

执行以上代码,输出结果为:

15

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!