erlang中变量作用域

erlang中变量只能一次赋值,这么“苛刻“的要求下,更别想拥有全局变量了。
变量只在function中存在,这就是函数编程语言的特色。
对于函数参数对应的变量从执行函数开始,到函数执行结束(从咱们编程者的角度来看的确如此,至于从运行时,GC的角度看,咱们就不深究了)。
比如下面的函数:

test1(V) ->
io:format("V is:~p~n", [V]),
% .... other routine
V.

test执行,V进行pattern match,绑定数值,随后进入函数体,执行各种操作。最后test返回,V也就结束了其使命。

如果变量是在函数体内部声明,那么在其声明后知道函数结束均可使用,比如
test2() ->
% do something
% ....
V = 10,
io:format("V is:~p~n", [V]),
% ....
V.


在erlang中fun也是一种数据类型,如果我在函数中定义一个fun,他们之间的参数关系如何呢?函数中匿名函数的参数会把所在函数的同名参数给屏蔽!
是不是有点罗嗦?看例子:
test3(V) ->
F = fun(V) -> % 这个V会屏蔽掉test3/1的参数V!
io:format("i'm V in fun:~p~n", [V])
end,
F(1),
F(V).


这里F匿名函数的V会屏蔽掉test3/1的V,如果你真的想使用test3/1的参数怎么办呢?别糊涂了,直接把F匿名函数的参数改个名字就结了,比如F = fun(V2)... 我写代码时还真有糊涂的时候。
关于屏蔽变量,编译器会提醒你:variable 'V' shadowed in 'fun',多么贴心的编译器。(这个对应一个编译器选项:warn_shadow_vars 默认编译存在)

关于变量我还有最后一个注意需要说明,那就是不要写”不安全的变量“,什么意思?看下面这个例子
test4(V) when is_integer(V) ->
if
V >= 0 ->
T1 = -V;
V < 0 ->
T2 = -V
end,
io:format("T1 is:~p~n", [T1]),
io:format("T2 is:~p~n", [T2]).


如果你编译这个代码片段,编译器肯定要说:
variable 'T1' unsafe in 'if' ...
variable 'T2' unsafe in 'if' ...

人家说,你的T1,T2都不是安全的变量!因为你的T1,T2的存在依赖与V的数值,如果V大于等于0,那么T2就不会绑定数值,如果V小于0,那么T1就不会绑定数值,
因此你的T1和T2都有可能不存在,能让这样的代码编译通过,那erlang肯定是睡着了。怎么修改呢?方法只有一个:让变量安全。
我们让所有的if的子句(guard seq)中都有某个变量,那么不论你在if中执行路径如何,我都能存在就OK了。
test4(V) when is_integer(V) ->
if
V >= 0 ->
T1 = -V,
T2 = 0;
V < 0 ->
T1 = 0,
T2 = -V
end,
io:format("T1 is:~p~n", [T1]),
io:format("T2 is:~p~n", [T2]).


编译一下,怎么样,我们的T1,T2现在都是安全的变量了吧。
好的,变量作用域相关的介绍暂时就这么多了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值