Erlang Programming 笔记 1
1. Erlang 优势
- 并发和分布式
- 主流语言使用共享内存模型,类似于
x = x + n
的代码导致了在多核环境下需要小心的处理锁的问题 - Erlang 使用消息模型,Process 间不共享数据,从而避免了锁的问题
- 无锁避免了顺序瓶颈,添加节点到网络更容易
- 主流语言使用共享内存模型,类似于
- 错误处理
- 多数语言默认认为程序不会出错
- Erlang 采用不同的设计决策——注定要出错,那就让他出错,出错后恢复就行了。即 Erlang 程序出错后,会交由更高级的 Process 来处理(重启 Child Process、系列全部终止、重启相关 Process 等等),从而实现对错误的分级和容错处理
- 同时带来了热更新的好处,进一步保证了可用性
2. 入门
- Shell
f().
会释放所有绑定的变量- 崩溃文件分析
webtool:start().
- 原子
- 使用单引号括起来的字符也是原子
- 这使得原子可以以大写字母开头,或者带有空格
'a' = a. %a 'Monday'. 'an atom with spaces'.
- 列表
- 可以包含不同类型
- 访问列表的头是高效的,所以通常函数处理也从列表头取起
- 插入元素到列表头部是高效的
A = ["a","b"]. C = ["c","d" | A ]. % ["c","d","a","b"]
- 尽量避免使用
List ++ [H]
这样的操作,通常情况下添加元素到列表尾部是极为低效的(重新生成新的列表),只有在列表非常短的时候可以这样用 - 添加在头部然后使用
lists:reverse/1
反转通常比添加在列表尾部效率要高 - 尽量使用经过高度优化的 BIF ,比如反转列表
lists:reverse/1
,可以从源码中找到它的定义,但是这个定义通常是作为简单的声明,实际上编译器会使用这个函数在系统内部更为高效的版本
- 尽量避免使用
- 字符串
- 严格说来 Erlang 中并没有字符串
- 字符串实际上是整数列表的一种「速记/代表」形式
-
可用
$
来表示字符串的整数值A = $a. % 97
3. 顺序型编程
- beam
beam 是 Bogdan's Erlang Abstract Machine 的缩写
- 匿名函数 fun
- fun 也可以拥有多个子句
TempFun = fun ({square, X}) -> X*X; ({double,X}) -> X+X end.
- fun 也可以拥有多个子句
- 列表解析
- 列表解析实现最简单的 Map
map(F, L) = [F(X) || X <- L].
- 列表解析中的生成器实际上也可以起到过滤的作用
[ X || {X, _} <- [ a,{c, d}, "aa", {"c", e}]]. % [ c, "c"]
- 快排算法
qsort([]) -> []; qsort([Pivot | T]) -> qsort([X || X <- T, X < Pivot]) ++ [H] ++ qsort([X || X <- T, X >= Pivot]).
- 毕达哥拉斯三元组
pythag(N) -> [{A, B, C} || A <- lists:seq(1, N), B <- lists:seq(1, N), C <- lists:seq(1, N), A + B + C =< N, A*A + B*B =:= C*C ].
- 全排列
perms([]) -> [[]]; perms(List) -> [ [H | T] || H <- L, T <- perms(L -- [H]) ].
- 列表解析实现最简单的 Map
- 断言
- 以 when 开头
- 用
;
隔开的断言,只要有一个为true
则断言序列成立 - 用
,
隔开的断言,只有全部为true
断言才会成立 - 合法的断言必须保证没有副作用,可以包含一些无副作用的 BIF ,但无法使用用户自定义的布尔表达式函数
-
-
=:=
代表精确等于,在比较的时候不会对数据类型进行转换=/=
代表精确不等于- 99% 的情况下应使用
=:=
或=/=
-
模式匹配中实际上是
=:=
,即f(12)
不会匹配到f(12.0)
1 == 1.0. % true 1 =:= 1.0。 %false
- 比较运算符的优先级
- 不同数据类型也可以比较大小,其优先级是:
<<"1">> > ["2"]. % true ["2"] > {"3"}. % true {"3"} > 'atom'. % true atom > 1. % true
- 不同数据类型也可以比较大小,其优先级是:
- record
- Record 实际上只是 tuple 的「伪装」,其本质上是一个 tuple
- case/if
- Erlang 中不存在多个 case 匹配一个执行块的语法
- Erlang 中任何表达式都是有值的,包括 case,因此可以有
X = case ... end
- Case 最后使用
_
, if 最后使用true
是保证所有分支得到匹配的方法
- 累加器
- 存储迭代过程中的临时容器
- posted on 2015-04-21 17:05
- erlang