Julia scoping specifics: defining closure within loop

后端 未结 1 363
执笔经年
执笔经年 2021-01-21 14:09

I am learning Julia using Ivo Balbaert\'s book. He uses the following example:

anon = Array{Any}(undef, 2)
for i = 1:2
    anon[i] = () -> println(i)
    i +         


        
相关标签:
1条回答
  • 2021-01-21 14:54

    This is pretty tricky. You need to know two things:

    • within a for loop variable i gets a fresh binding on every iteration (I guess you know it - I do not know Ivo's book, but from your question I guess this is what he is discussing in it)
    • in Julia closures are implemented via a creation of an object that captures a variable from an outer scope and then it can access it

    Now to explain the second point have a look at the following (I assume you have run the code above):

    julia> anon[1].i
    Core.Box(2)
    
    julia> anon[1].i.contents
    2
    

    And you can see that anon[1] has boxed the binding to i that was present in the first iteration of the loop. As in the second loop the binding to i is fresh anon[2] has a reference to this fresh binding.

    You can even access this memory location like this:

    julia> anon[1].i.contents = 100
    100
    
    julia> anon[1]()
    100
    

    or even like this (not recommended):

    julia> for i = 1:2
               anon[i] = () -> println(i)
               anon[i].i.contents = 100 + i
               i += 1
               println(i)
           end
    102
    103
    
    julia> anon[1]()
    102
    
    julia> anon[2]()
    103
    

    Finally note that within a single iteration of the loop assigning to variable i does not change the binding (you are writing to the same memory location).

    0 讨论(0)
提交回复
热议问题