scala基础学习-闭包

发布于:2025-03-01 ⋅ 阅读:(129) ⋅ 点赞:(0)

scala闭包

闭包

在 Scala 中,闭包是一个函数,它捕获了外部函数作用域中的变量。闭包可以访问并操作这些外部变量,即使外部函数已经执行完毕。闭包通常用于实现高阶函数、函数柯里化和其他函数式编程技术。

在 Scala 中,虽然可以在一个方法内部定义另一个方法(嵌套方法),但这种做法并不像在 Python 中那样常见。Scala 更倾向于使用函数字面量和匿名函数来实现闭包和高阶函数的功能。

以下是一个闭包的简单示例:

//: Int=>Int  证明返回值是一个函数,表达式
def makeMultiplier(factor: Int): Int => Int = {
  (x: Int) => factor * x
}

val timesTwo = makeMultiplier(2)
val timesThree = makeMultiplier(3)

println(timesTwo(5))  // 输出 10
println(timesThree(5)) // 输出 15


在这个例子中,makeMultiplier 函数接受一个整数 factor 作为参数,并返回一个新的函数,这个新函数接受一个整数 x 并返回 factor * x。返回的函数是一个闭包,因为它捕获了 factor 变量。

即使 makeMultiplier 函数已经执行完毕,返回的函数仍然可以访问 factor 变量。因此,timesTwotimesThree 这两个闭包可以分别使用不同的 factor 值。

闭包使用内置变量

object ClosureExample3 {
  def main(args: Array[String]): Unit = {
    var messages = List("Hello", "World")
	// 表达式为 messages = messages :+ msg  :+ 为列表追加
    val addMessage = (msg: String) => messages = messages :+ msg

    addMessage("Scala")
    println(messages)  // 输出 List(Hello, World, Scala)
      
    // 使用内部变量
    val factor = 8
    def makeMultiplier1() = {
      (x: Int) => factor * x
    }
	val one1 = makeMultiplier1()
    println(one1(2)) // 16

	}

}

内部变量的使用,使用闭包可以固定变量,不受变量更改而变化

//传入变量,但是调用会随着变量的更改而修改    
	var factor = 8
    def makeMultiplier1() = {
      (x: Int) => factor * x
    }

    val one1 = makeMultiplier1()
    println(one1(2)) //输出16

    factor = 9
    println(makeMultiplier1()(2)) //输出18

//使用闭包固定变量,不受变量更改而变化
    factor = 10
    def makeMultiplier(factor: Int) = {
      (x: Int) => factor * x
    }
	
	// one 接受了makeMultiplier(factor) 闭包已经固定,one 已经不在受factor变量影响了
    val one = makeMultiplier(factor)
    println(one(2)) //输出20

    factor = 11
    println(one(2)) //输出20

闭包的返回值

闭包返回函数

// Int => Int 表明返回对象为函数 返回表达式 (x: Int) => x + adder
def makeAdder(adder: Int): Int => Int = {
  (x: Int) => x + adder
}

//相当于val addFive = (x: Int) => x + 5
val addFive = makeAdder(5)
val addTen = makeAdder(10)

闭包与函数式编程

object ClosureExample4 {
  def main(args: Array[String]): Unit = {
      
    // 返回了一个调用结果在highOrderFunction内部直接调用f函数
    def highOrderFunction(f: Int => Int, x: Int): Int = f(x)
    val externalVar = 5
    val closure = (x: Int) => x + externalVar
    println(highOrderFunction(closure, 10))  // 输出 15
    // 相当于highOrderFunction
    println(closure(10))
  }
}

在函数式编程中,闭包经常与高阶函数一起使用。高阶函数可以接受闭包作为参数,这允许你传递具有特定行为的函数。以下是一个使用高阶函数和闭包的例子:

def operateOnList(list: List[Int], operation: Int => Int): List[Int] = {
  list.map(operation)
}
val addFive = (x: Int) => x + 5
val result = operateOnList(List(1, 2, 3), addFive)
println(result) // 输出 List(6, 7, 8)

在这个例子中,operateOnList 是一个高阶函数,它接受一个整数列表和一个操作函数作为参数。addFive 是一个闭包,它捕获了外部作用域中的变量(在这个例子中没有捕获任何变量,但它是潜在的闭包)。operateOnList 函数使用 addFive 函数对列表中的每个元素进行操作。

总之,在 Scala 中,闭包和函数式编程是紧密相关的概念。闭包允许你创建可以捕获和操作外部状态的函数,而函数式编程强调使用纯函数、高阶函数和不可变数据来创建可预测和模块化的代码。通过结合使用闭包和函数式编程,你可以创建强大和灵活的代码,这些代码易于理解和维护。


网站公告

今日签到

点亮在社区的每一天
去签到