官术网_书友最值得收藏!

Scope revisited

A variable that is defined at the top level is said to have global scope.

The for, while, and try blocks (but not the if blocks) all introduce a new scope. Variables defined in these blocks are only known to that scope. This is called the local scope, and nested blocks can introduce several levels of local scope. However, global variables are not accessible in for and while loops.

Variables with the same name in different scopes can safely be used simultaneously. If a variable exists both in global and local scope, you can decide which one you want to use by prefixing them with the global or local keyword:

  • global: This indicates that you want to use the variable from the outer, global scope. This applies to the whole of the current scope block.
  • local: This means that you want to define a new variable in the current scope.

The following example will clarify this, as follows:

# code in Chapter 4\scope.jl 
x = 9  
function funscope(n) 
  x = 0 # x is in the local scope of the function 
  for i = 1:n 
    local x # x is local to the for loop 
    x = i + 1 
    if (x == 7) 
        println("This is the local x in for: $x") #=> 7 
    end 
  end 
  x 
  println("This is the local x in funscope: $x") #=> 0 
  global x = 15 
end 
 
funscope(10) 
println("This is the global x: $x") #=> 15 

This prints out the following result:

This is the local x in for: 7 
This is the local x in funscope: 0 
This is the global x: 15 

If the local keyword was omitted from the for loop, the second print statement would print out 11 instead of 7, as follows:

This is the local x in for: 7 
This is the local x in funscope: 11 
This is the global x: 15 

What is the output when the global x = 15 statement is left out? In this situation, the program prints out this result:

This is the local x in for: 7 
This is the local x in funscope: 11 
This is the global x: 9

However, needless to say, such name conflicts obscure the code and are a source of bugs, so try to avoid them if possible.

If you need to create a new local binding for a variable, use the let block. Execute the following code snippet:

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

Here, both anon[1] and anon[2] are anonymous functions. When they are called with anon[1]() and anon[2](), they print 2 and 3 (the values of i when they were created plus one). What if you wanted them to stick with the value of i at the moment of their creation? Then, you have to use let and change the code to the following:

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

Now, anon[1]() and anon[2]() print 1 and 2, respectively. Because of let, they kept the value of i the same as when they were created.

The let statement also introduces a new scope. You can, for example, combine it with begin, like this:

begin 
    local x = 1 
    let 
       local x = 2 
       println(x) #> 2 
    end 
    x 
    println(x) #> 1 
end

for loops and comprehensions differ in the way they scope an iteration variable. When i is initialized to 0 before a for loop, after executing for i = 1:10 end, the variable i is now 10:

i = 0 
for i = 1:10 
end 
println(i)  #> 10 

After executing a comprehension such as [i for i = 1:10], the variable i is still 0:

i = 0 
[i for i = 1:10 ] 
println(i)  #> 0 
主站蜘蛛池模板: 林周县| 隆尧县| 中西区| 长顺县| 湟源县| 凤城市| 巴林右旗| 诸暨市| 乐平市| 谷城县| 临沭县| 绍兴市| 宝坻区| 山东省| 雅江县| 曲水县| 浏阳市| 东城区| 乳源| 泾川县| 南昌县| 常熟市| 定西市| 常熟市| 五原县| 申扎县| 昌黎县| 蒲城县| 武清区| 东乡县| 西乌| 门源| 河池市| 沈阳市| 共和县| 闵行区| 晴隆县| 黑山县| 定远县| 蒙阴县| 上犹县|