scala 如果我想创建一个内部函数,它将访问外部作用域变量,但它不能是一个闭包,这可能吗?

mfpqipee  于 5个月前  发布在  Scala
关注(0)|答案(1)|浏览(53)

我想明白的是,如果我有用例,也就是内部函数需要访问外部作用域变量,但它不能是闭包(即使外部函数完成执行,它也不能记住变量的值)
我没办法创造一个
检查以下scala代码

object ExternalVariableExample extends App {

  // Outer function
  def outerFunction(): Int => Int = {
    // External variable
    var outerVariable = 0

    // Inner function (closure) accessing the external variable
    (x: Int) => {
      outerVariable += x
      outerVariable
    }
  }

  // Create a closure
  val closure = outerFunction()

  // Call closure multiple times
  val result1 = closure(5)  // Output: 5 (outerVariable = 0 + 5)
  val result2 = closure(3)  // Output: 8 (outerVariable = 5 + 3)

  // Print results
  println(s"Result 1: $result1")
  println(s"Result 2: $result2")
}

字符串
val result1 = closure(5)执行完毕时,outerVariable的值变为5(0 + 5),由于val result2 = closure(3)执行时关闭,outerVariable的值仍为5,因此变为8(5 + 3)
现在我需要的是,我有内部函数,因为我需要访问外部作用域变量,但是当我用不同的值调用多次时,无论我访问的是什么外部作用域变量,它都不应该记住上一次调用的值。它应该重置为声明的值,即outerVariable = 0
我希望我的要求是有效的,如果不是事先道歉。

x8diyxa7

x8diyxa71#

你在这里做什么

// Outer function
def outerFunction(): Int => Int = {
  // External variable
  var outerVariable = 0

  // Inner function (closure) accessing the external variable
  (x: Int) => {
    outerVariable += x
    outerVariable
  }
}

val closure = outerFunction()
val result1 = closure(5) // Output: 5 (outerVariable = 0 + 5)
val result2 = closure(3) // Output: 8 (outerVariable = 5 + 3)

字符串
如果你做一些事情,

class OuterClass {

  private var outerVariable: Int = 0

  def innerFunction(x: Int) = {
    outerVariable += x
    outerVariable
  }
}

val outerClass = new OuterClass()
val result1 = outerClass.innerFunction(5)
val result2 = outerClass.innerFunction(3)


不确定您的用例是什么,但看起来您试图为相同的输入获取相同的值,这称为pure function

  • 一个函数f是纯的,如果给定相同的输入x,它总是返回相同的输出f(x)
  • 函数的输出仅取决于其输入变量及其实现
  • 它只计算输出,不修改周围的世界

在这种情况下,你可以这样做,

def ComposableFunction: Int => Int => Int = {
  (outer: Int) => {
    (inner: Int) => {
      outer + inner
    }
  }
}

val composableFunction: Int => Int = ComposableFunction(0)
val result1: Int = composableFunction(5)
val result2: Int = composableFunction(3)


这将打印

Result 1: 5
Result 2: 3


正如你所看到的,我改变了函数的结果类型。现在我返回的不是Int => Int函数,而是Int => Int => Int
在第一个调用中,我使用0作为参数调用ComposableFunction

val composableFunction: Int => Int = ComposableFunction(0)


0的值存在于composableFunction中,每次我调用高阶函数,传递不同的值作为参数时,它将始终应用使用0的逻辑,并且不会改变,除非我调用函数ComposableFunction(anotherValue)并将其保存到新的val

val composableFunction3 = ComposableFunction(3)
val result1 = composableFunction3(5)
val result2 = composableFunction3(8)


并且结果将是

Result 1: 8
Result 2: 11


所有这些概念都来自Functional Programming范式。
下面的文章可能有助于更好地理解如何应用这些概念

在Coursera上也有一门关于函数式编程的好课程

相关问题