维基百科上的Scala闭包

Sch*_*jer 9 closures scala

维基百科上的Closure页面上找到以下代码段

//# Return a list of all books with at least 'threshold' copies sold.
def bestSellingBooks(threshold: Int) = bookList.filter(book => book.sales >= threshold)
//# or
def bestSellingBooks(threshold: Int) = bookList.filter(_.sales >= threshold)
Run Code Online (Sandbox Code Playgroud)

如果我错了,请纠正我,但这不是关闭?它是一个函数文字,一个无关函数,一个lambda函数,但不是一个闭包?

Fla*_*gan 14

好吧......如果你想成为技术人员,这是一个函数文字,它在运行时被翻译成一个闭包,关闭开放的术语(将它们绑定到函数文字范围内的val/var).此外,在此函数literal(_.sales >= threshold)的上下文中,threshold是一个自由变量,因为函数文本本身并没有赋予它任何含义.它本身_.sales >= threshold就是一个开放的术语在运行时,每次调用函数时,它都绑定到函数的局部变量.

以此函数为例,生成闭包:

def makeIncrementer(inc: Int): (Int => Int) = (x: Int) => x + inc
Run Code Online (Sandbox Code Playgroud)

在运行时,以下代码生成3个闭包.值得注意的是,b和c不是相同的闭包(b == c给出false).

val a = makeIncrementer(10)
val b = makeIncrementer(20)
val c = makeIncrementer(20)
Run Code Online (Sandbox Code Playgroud)

我仍然认为在维基百科上给出的例子是一个很好的例子,尽管并不完全覆盖整个故事.通过最严格的定义给出一个实际闭包的例子是非常困难的,而实际上没有运行程序的内存转储.它与类 - 对象关系相同.你通常通过定义一个对象class Foo { ...然后用它来实例化一个对象的例子val f = new Foo,说f是对象.

-- Flaviu Cipcigan

笔记:

  • 参考:Scala编程,Martin Odersky,Lex Spoon,Bill Venners
  • 使用在Java 1.6.0_14上运行的Scala版本2.7.5.final编译的代码.