May 14, 2021 Julia
The scope of a variable is the area where the variable is visible. Variable scopes can help avoid variable naming conflicts.
A scope block is a region of code that is the scope of a variable. T he scope of the variables is limited to the inside of these blocks. Scope blocks are:
Note that the begin block cannot introduce a new scope block.
When a variable is introduced into a scope, all internal scopes inherit the variable unless an internal scope explicitly copies it. Ways to introduce new variables into the current scope:
local x
const x
introduce new local variables
global x
causes
x
to introduce the current scope and the innerer scope
x = y
x
x
a global variable or introduced as a local variable in any outer scope
In the following example, inside and outside the loop, only one
x
assigned:
function foo(n)
x = 0
for i = 1:n
x = x + 1
end
x
end
julia> foo(10)
10
In the following example, the loop body has a separate
x
and the function always returns 0:
function foo(n)
x = 0
for i = 1:n
local x
x = i
end
x
end
julia> foo(10)
0
In the following example,
x
inside the loop body, so the function encounters an undefined error on the last line
x
has been declared a global variable):
function foo(n)
for i = 1:n
x = i
end
x
end
julia> foo(10)
in foo: x not defined
The only way to assign value to a global variable in a non-top scope is to explicitly declare that the variable is global in a scope. Otherwise, assignments introduce new local variables instead of assigning values to global variables.
You don't have to introduce x on an external assignment before you use
x
function foo(n)
f = y -> n + x + y
x = 1
f(2)
end
julia> foo(10)
13
The example above may seem strange, but it's no problem. B ecause here is a function bound to a variable. T his allows us to define functions in any order without having to declare them from the bottom up or in advance like C. Here's an inefficient example of recursively validating a positive parity:
even(n) = n == 0 ? true : odd(n-1)
odd(n) = n == 0 ? false : even(n-1)
julia> even(3)
false
julia> odd(3)
true
Julia has built-in
iseven
isodd
to verify parity.
Because functions can be called and then defined, there is no need to declare in advance, and the order of definitions can be arbitrary.
In interactive mode, you can hypothesically have a layer of scope block packages outside of any input, similar to global scopes:
julia> for i = 1:1; y = 10; end
julia> y
ERROR: y not defined
julia> y = 0
0
julia> for i = 1:1; y = 10; end
julia> y
10
In the previous example,
y
only
for
loop. I
n the latest example, the externally
y
is introduced into the loop. B
ecause the scope of the session is similar to the global scope, you do not have to declare
global y
However, code that does not run in interactive mode must declare a global variable.
Multivariables can be declared global using the following syntax:
function foo()
global x=1, y="bar", z=3
end
julia> foo()
3
julia> x
1
julia> y
"bar"
julia> z
3
let
statement provides another way to introduce variables.
let
statement declares a new variable each time it runs.
let
syntax accepts assignment statements or variable names separated by commas:
let var1 = value1, var2, var3 = value3
code
end
let x = x
syntax because the two
x
are different. I
t first values the right side, then introduces a new variable on the left and assigns a value.
Here's an example of what you need to do with
let
Fs = cell(2)
i = 1
while i <= 2
Fs[i] = ()->i
i += 1
end
julia> Fs[1]()
3
julia> Fs[2]()
3
The return values of the two closures are the same.
If you
let
variable i with
i
Fs = cell(2)
i = 1
while i <= 2
let i = i
Fs[i] = ()->i
end
i += 1
end
julia> Fs[1]()
1
julia> Fs[2]()
2
Because
begin
block does not introduce new scope blocks, it is useful to use let to introduce new scope blocks:
julia> begin
local x = 1
begin
local x = 2
end
x
end
ERROR: syntax: local "x" declared twice
julia> begin
local x = 1
let
local x = 2
end
x
end
1
The first example is that a local variable with the same name cannot be declared in the same scope.
In the second example,
let
introduces a new scope block, where the local variable
x
from the local variable x of the
x
layer.
For loops and
Comprehensions have special
behavior: the new variables declared in them are re-declared in each loop.
Therefore, it is a bit like a
let
with an
while
block:
Fs = cell(2)
for i = 1:2
Fs[i] = ()->i
end
julia> Fs[1]()
1
julia> Fs[2]()
2
for
loop iterates with variables that already exist:
i = 0
for i = 1:3
end
i # here equal to 3
However, comprehensions, in contrast, always declares new variables:
x = 0
[ x for x=1:3 ]
x # here still equal to 0
const
keyword tells the compiler to declare a constant:
const e = 2.71828182845904523536
const pi = 3.14159265358979323846
const
can declare global and local constants, preferably using it to declare global constants. T
he value (or even type) of a global variable can change at any time, and it is difficult for the compiler to optimize it.
If the global variables do not change, you can add a
const
to resolve performance issues.
Local variables are different. The compiler can automatically infer whether a local variable is a constant, so the declaration of a local constant is not necessary.
Special top-level assignments default to constants, such as
function
and
type
keywords.
Note
const
has only an effect on the binding of variables, which can be bound to a variable object, such as an array, that can still be modified.