# 试写一个Julia Scoping作用域的中文讲解

## 丢了的玩具-从UndefVarError说起

9成情况下，肇事者写了这样一个程序，引起了Julia不满

``````#Scoping
a=1
for i =1:20
a+=1
end
``````

``````UndefVarError: a not defined
in top-level scope at base\none
in top-level scope at Scoping.jl:4
``````

global a

``````a=1
for i = 1:20
global a+=1
end
a
``````

``````let
a=1
for i = 1:20
a+=1
end
a
end
``````

## Scope的global,local不影响读取，

``````x=1
for i = 1:10
a=i^2
println("a="*string(a))
for j = 1:10
println(i+j+a)
println(x)
end
end

``````

## 被滥用的let-end

``````a=1
for i = 1:10
global a = 1
global a = a+i
show(a)
end
a

a=1
for i = 1:10
local a = 1
local a = a+i
show(a)
end
a
``````

## Scoping的种类以及控制

function对应hard scope
for,while等loop对应soft scope

soft scope 可以用global，local 来加以区分扔出去的东西和循环内部自己的东西
function 可以用module管理（不过如果你的程序不涉及太多函数的话没什么必要），每个module 要用import来加载

### 函数无global

``````function f(x)
for i in 1:3
x=x^2
end
return x
end

f(2)
``````

···
256
···

## 常见错误

1.在多层循环里用global之前不先放一个global变量在global上

``````for i in 1:10
for j in 1:10
global a =i*j
end
if i*j>1
show(1)
end
end
``````

5 个赞

``````x = [1 2;3 4]
x

function times2(x::Array)
x*2
end

times2(x)
x

``````

but…

``````function times2!(x::Array)
x[:,:] = x[:,:].*2
return x
end
times2!(x)
x
``````

``````
function times2_2!(x::Array)
y=x
y[:,:] = x[:,:]*2
return x
end

x
times2_2!(x)
x
``````

``````function times2_2(x::Array)
y = zeros(size(x))
y[:,:] = x[:,:]
y[:,:]*=2
y
end
x
times2_2(x)
x

``````

2 个赞

``````
function times2_3(x::Array)
y = copy(x)
y[:,:] *=2
return y
end

x
times2_3(x)
x
``````
1 个赞

copy的存在使得编程的便利性增强，Julia的规则真是让人用起来太不顺心了

for循环这些实现成non-scoped一样有一堆人骂。目前这个设计就是最好的，你觉得复杂，原因不外乎变量写入时的作用域规则。

``````a = Ref(value)
a[] #读可变变量
a[] = value #写可变变量
``````