私の理解によると、これrandList
は間違いなくクロージャではありません (ウィキペディアは同意しているようです)。これは、提供したコードのスニペットでは、ローカル変数にのみ依存するためです (パラメーターもローカル変数と見なされます)。の本体を考えると、randList
いわゆる自由変数、つまり現在の字句スコープから値を取得しない変数はありません。後者はメソッド本体そのものです。len
とn
は両方とも、 の囲み定義のパラメータであるため、現在のレキシカル スコープの変数です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
いますが、今は this を使用していると思われるかもしれません。ただし、クロージャーは、その宣言を囲むレキシカルスコープに結合されています。これは、が評価されるときにの値が取得される場所です。foo
n
f
n
f
n
f