为什么以下Scala函数被称为闭包?

时间:2012-09-27 06:10:08

标签: scala closures

对于以下问题:http://pastie.org/4825115,这是我的代码:http://pastie.org/private/n22zohyshn2ymqrbrb3g

def randList(len: Int, n: Int): List[Int] = len match {
  case 0 => List()
  case len => scala.util.Random.nextInt(n) :: randList(len-1, n)
}

但我不知道为什么randList被称为闭包。

3 个答案:

答案 0 :(得分:17)

根据我的理解randList肯定一个闭包(Wikipedia似乎同意),因为 - 在你提供的代码片段中 - 它只取决于本地变量(参数也被认为是局部变量)。考虑randList的主体,没有所谓的自由变量,即没有从当前词法范围获取其值的变量,其中后者是方法体本身。 lenn都是当前词法范围的变量,因为它们都是randList的封闭定义的参数。

考虑这个例子:

var n = 10
val f = (x: Int) => x + n

println(f(1)) // 11

n = 20
println(f(1)) // 21

函数f是一个闭包,因为它不仅取决于它的参数,还取决于在其自己的词法范围之外声明的变量(即n)。

维基百科的文章提到闭包是由一个函数和一个声明自由参数的词法范围定义的。下一个例子说明了这一点:

// n == 20
// f as above

def foo(g: Int => Int) = {
  val n = 100
  g(1)
}

println(foo(f)) // 21

foo(f)的结果仍为21,尽管foo定义了自己的局部变量n,可以假设f现在使用此n f 1}}。但是,闭包n与声明周围的词法范围相关联,这是f在评估{{1}}时的值。

答案 1 :(得分:0)

我同意@Malte,因为randList不依赖于在函数外声明的任何变量。所以这个函数不是闭包。

答案 2 :(得分:-1)

据我所知,闭包是一个可以在另一个函数中引用状态的函数。查看此主题以获取更多详细信息:What is a 'Closure'?

在这个问题中,由于randList没有引用任何外部变量,所以它不是闭包......