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现在都是安全的变量了吧。
好的,变量作用域相关的介绍暂时就这么多了。
分享到:
相关推荐
- **1.2.9 变量的匹配、守卫和作用域**:深入讲解Erlang中变量的行为和模式匹配。 - **1.2.10 更多关于列表**:讲解列表的高级特性。 - **1.2.11 If和Case**:解释条件语句的使用。 - **1.2.12 内建函数(BIFs)**:...
Erlang中的变量作用域遵循局部作用域原则。变量在其定义的作用域内可见,并且在离开该作用域时不再可访问。这种设计有助于避免命名冲突和减少调试的复杂度。 **3.1 列表处理内置函数** Erlang提供了一系列用于处理...
- **作用域**: 变量的作用域限制了其可见性和生命周期。 - **更多关于列表**: - **列表推导**: 列表推导允许用户简洁地创建新列表。 - **列表操作**: 包括列表合并、过滤、映射等功能。 - **高级用法**: 如递归...
- 变量在Erlang中的作用域是有限的,通常局限于函数体内。 - 理解变量的作用域有助于避免常见的错误。 ##### 第3章:使用列表编程 **3.1 列表处理内置函数** - Erlang提供了丰富的列表处理内置函数。 - 这些函数...
- **变量匹配和作用域**: Erlang的变量匹配机制允许在赋值时检查和提取数据结构的特定部分,而变量作用域的规则确保了代码的清晰和正确。 ### 并行编程 并行编程是Erlang的核心特性之一,它通过进程来实现并发。 ...
- **核心概念**:深入讲解Erlang的核心概念,例如变量的作用域、模式匹配、递归循环以及进程间通信等。 - **实际应用**:通过具体的代码示例,展示如何在实际项目中运用这些概念来解决问题。 #### 变量的作用域 **...
- **变量匹配、守卫和作用域**:深入解释了变量绑定、模式匹配和作用域规则。 - **列表操作**:展示了更多的列表操作技巧。 - **条件语句**:讲解了`if`和`case`语句的使用。 - **内置函数**:介绍了Erlang的...
这包括用于处理临时数据的分配器,如C函数作用域、临时GC根集、分布式消息解码、ets模式规格和短期计时器。标准分配器用于处理标准生命周期的数据,例如链接和监控器。长期分配器用于管理代码和原子。还有固定大小的...
- **变量作用域** 定义了变量在程序中的可见范围。 ##### 3.10 关于列表的更多内容 - **列表** 在 Erlang 中有着广泛的应用,包括列表操作、列表排序等高级功能。 ##### 3.11 If 和 Case - **If** 和 **Case** ...
手册中详细介绍了变量的声明、使用方法及其作用域规则。 **1.6.4 模式** 模式是用于表示数据结构特征的一种特殊语法。手册中详细介绍了模式的概念、定义方法及其在模式匹配中的应用。 **1.6.5 匹配** 匹配是 ...
Golang的for range循环实际上是对容器内的元素进行了一层封装,通过迭代器遍历元素,并在内部进行了临时变量的复用,这在并发环境下可能不是线程安全的,因此需要注意变量的作用域和生命周期。 此外,Golang采用的...
8. **闭包**:函数可以记住其定义时的作用域,即使在该作用域不再存在时也能访问其变量,提供了一种实现状态的方式,但不改变外部状态。 【函数式编程的实际应用】 虽然函数式编程在学术领域有深厚基础,但在实际...
自由变量是指在函数定义的外部作用域中定义的变量。 6. 函数组合(Function composition):函数组合是将两个或多个函数组合成一个函数的过程。这是函数式编程中的一个强大概念,可以组合简单的函数来解决复杂问题...