本文主要是介绍julia-变量作用域(第11讲),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1.1.分类:全局作用域和局部作用域(可嵌套)
1.2.说明:Julia使用词法作用域,即函数作用域不从调用者作用域继承,而从定义函数作用域继承
1.3.作用域块构造:Construct构造 Scope type范围类型 Scope blocks it may be nested in范围块可以嵌套在其中module, baremodule global globalinteractive prompt (REPL)互动提示 global global(mutable) struct, macro local globalfor, while, try-catch-finally, let local global or localfunctions (either syntax, anonymous & do-blocks) local global or local 语法,匿名和执行块comprehensions, broadcast-fusing local global or local该表中明显缺少begin块和if块,它们没有引入新的作用域。1.4.全局变量每个模块都引入一新的全局范围,仅作用于该模块;没有涵盖所有领域的全局变量模块通过using或import或点符号的限定访问将其他模块的变量引入其作用域,变量绑定只能在其全局范围内更改,而不能从外部模块更改。1.5.局部变量大多数代码块都引入了新本地范围;本地作用域从父本地作用域继承所有变量,以进行读取和写入。局部作用域不是名称空间,内部作用域中的变量无法通过某种合格的访问从父作用域中检索。在局部范围内所有变量均从其父全局范围块继承,除非分配给global or local
2.实例:
2.1.全局变量实例
实例1.1:module Barx = 1 # 模块Bar全局变量foo() = x # 引用模块Bar的全局变量end;import .Bar # 词法作用域意味着可仅从源代码推断变量范围x = -1;Bar.foo() # 1实例1.2.:module Aa = 1 # 模块全局变量end;module Bmodule Cc = 2endb = C.c # 可以访问嵌套全局范围的命名空间import ..A d = A.aend;module Db = a # UndefVarError: a not definedend;module Eimport ..A A.a = 2 # ERROR: cannot assign variables in other modulesend;
2.2.局部变量实例实例2.1:
for i = 1:10z = i # UndefVarError: z not defined
end实例2.2:
for i = 1:1z = ifor j = 1:1 z = 0 end # 内部局部范围可以更新其父范围中的变量println(z) # 0
end实例2.3:
for i = 1:1x = i + 1for j = 1:1 local x = 0 end # 在局部范围内将变量强制为新的局部变量println(x) # 2
end实例2.4:local和global变量(必须显式指定)在范围块内顺序是无关紧要
for i = 1:10 global z =i end #局部范围内声明修改global变量
for i = 1:10 z = i;global z end #等价上面比较糟糕
z # 10
实例2.5:嵌套函数可修改其父范围的局部变量:
x, y = 1, 2;function baz()x = 2 # 局部变量function bar()x = 10 # 修改局部变量return x + y # y is globalendreturn bar() + x # 12 + 10 (x is modified in call of bar())
end;baz(),x, y # (22, 1, 2) x,y不改变实例2.6:
let state = 0global counter() = (state += 1)
end;counter()# 1
counter()# 2实例2.7:
x, y = 1, 2;function bar()x = 10 # local, no longer a closure variablereturn x + y
end;function quz()x = 2 # localreturn bar() + x # 12 + 2 (x is not modified)
end;quz(), x, y # (14, 1, 2) x,y不改变
实例2.8:引入一个在函数,类型或宏定义内部使用的变量的赋值不必先于其内部使用:
f = y -> y + a;
f(3)# ERROR: UndefVarError: a not defined
a = 1
f(3)# 4even(n) = (n == 0) ? true : odd(n - 1);
odd(n) = (n == 0) ? false : even(n - 1);even(3),odd(3)# (false, true)
实例3:let块1). let语句每次运行时都会分配新变量绑定;
2).分配按顺序进行评估,在引入左侧新变量前将在范围中对每个右侧进行评估let x = x两个x变量是不同的并且具有独立的存储
3).这种差异通常并不重要,只有在通过闭包超出其作用域的变量的情况下才可以检测到。实例3.1:
x, y, z = -1, -1, -1;let x = 1, zprintln("x: $x, y: $y") # x is local variable, y the globalprintln("z: $z") # errors as z has not been assigned yet but is local
end# x: 1, y: -1
# ERROR: UndefVarError: z not defined实例3.2: 创建并存储两个返回变量i的闭包;它始终是相同变量i,因此两个闭包的行为相同
Fs = Vector{Any}(undef, 2); i = 1;
while i <= 2Fs[i] = ()->iglobal i += 1
endFs[1](),Fs[2]()# (3, 3)实例3.3:用let创建新的绑定i
Fs = Vector{Any}(undef, 2); i = 1;
while i <= 2let i = iFs[i] = ()->iendglobal i += 1
endFs[1](),Fs[2]()# (1, 2)
实例4:begin构造不会引入新作用域,用零参数let仅引入一新作用域块而不创建任何新绑定
# 由于let引入了新的作用域块,因此内部局部x变量与外部局部变量是不同的变量x
letlocal x = 1letlocal x = 2endx # 1
end
实例5:循环for,while
# 在其主体范围中引入任何新变量都将为每次循环迭代新鲜分配,像循环主体被一个let块包围一样:Fs = Vector{Any}(undef, 2);
for j = 1:2 Fs[j] = ()->j endFs[1](),Fs[2]()# (1, 2)# 一个for循环或理解迭代变量始终是一个新变量:
function f()i = 0for i = 1:3endreturn i
end;f()# 0# 重用现有局部变量作为迭代变量outer:function f()i = 0for outer i = 1:3endreturn i
end;f()# 3
这篇关于julia-变量作用域(第11讲)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!