闭包简介

函数是 Julia 编程的重要组成部分。它们可以直接在模块中定义,在这种情况下,函数称为顶级。但是函数也可以在其他函数中定义。这些功能称为“ 闭包 ”。

闭包捕获外部函数中的变量。顶级函数只能使用其模块,函数参数或局部变量中的全局变量:

x = 0  # global
function toplevel(y)
    println("x = ", x, " is a global variable")
    println("y = ", y, " is a parameter")
    z = 2
    println("z = ", z, " is a local variable")
end

另一方面,闭包可以使用除了捕获的外部函数的变量之外的所有变量:

x = 0  # global
function toplevel(y)
    println("x = ", x, " is a global variable")
    println("y = ", y, " is a parameter")
    z = 2
    println("z = ", z, " is a local variable")

    function closure(v)
        println("v = ", v, " is a parameter")
        w = 3
        println("w = ", w, " is a local variable")
        println("x = ", x, " is a global variable")
        println("y = ", y, " is a closed variable (a parameter of the outer function)")
        println("z = ", z, " is a closed variable (a local of the outer function)")
    end
end

如果我们运行 c = toplevel(10),我们会看到结果是

julia> c = toplevel(10)
x = 0 is a global variable
y = 10 is a parameter
z = 2 is a local variable
(::closure) (generic function with 1 method)

请注意,此函数的尾部表达式本身就是一个函数; 也就是说,关闭。我们可以像关闭任何其他函数一样调用闭包 c

julia> c(11)
v = 11 is a parameter
w = 3 is a local variable
x = 0 is a global variable
y = 10 is a closed variable (a parameter of the outer function)
z = 2 is a closed variable (a local of the outer function)

请注意,即使 toplevel 已经返回,c 仍然可以从 toplevel 调用访问变量 yz! 每个闭包,即使是由相同函数返回的闭包,也会关闭不同的变量。我们可以再次调用 toplevel

julia> d = toplevel(20)
x = 0 is a global variable
y = 20 is a parameter
z = 2 is a local variable
(::closure) (generic function with 1 method)

julia> d(22)
v = 22 is a parameter
w = 3 is a local variable
x = 0 is a global variable
y = 20 is a closed variable (a parameter of the outer function)
z = 2 is a closed variable (a local of the outer function)

julia> c(22)
v = 22 is a parameter
w = 3 is a local variable
x = 0 is a global variable
y = 10 is a closed variable (a parameter of the outer function)
z = 2 is a closed variable (a local of the outer function)

请注意,尽管 dc 具有相同的代码,并且传递相同的参数,但它们的输出是不同的。它们是截然不同的封闭物。