1、基础
Ctrl+C 输入a 强制退出命令界面,输入q(). 受控关闭 (q()是init:stop()命令在shell 里的别名)
erlang:halt(). 立即停止系统
# 打开erlang命令界面
erl
# 查看帮助界面
help().
# 第二个帮助
ctrl + G
h
# 退出方式1
q().
# 退出方式2
ctrl + G
q.
X = 20.
X + 20. % 百分号后面的全部代表注释
//输出 40
Erlang可以用任意长度的整数执行整数运算。并且是精准的,不用担心溢出或长度不够。
Erlang的变量不会变,不能多次赋值。=是一个模式匹配操作符。
X = 4 + 2.
Y = 10.
//正常打印6 ,匹配成功
X = 6.
//匹配失败,抛异常
X = Y.
2#101010. #二进制表示
8#0677. #八进制表示
16#AE. #十六进制表示
浮点数 3.0
当做除法运算,会自动转成浮点数。 (5/3. 1.666666666666) (4/2. 2.0)
5 div 3. 舍弃余数,去整数
5 rem 3. 获取5除以3的余数
原子(常量)全局性的
原子以小写字母开头,后接一串字母、数字、下划线(_)或at(@)符号
’ 添加单引号的元子可以使用大写开头。'Monday'、'Tuesday'。('a' 与 a 意思完全一致)
一个原子的值就是它本身。(hello. -> hello)
元组{} 类似java里的数组,元组用于保存固定数量的 元素
P = {joe,1.82}. //joe身高1.82 Sit = {10,5} //坐标
F = {firstName,joe}.
L = {lastName,armstrong}.
P = {person,F,L}.
//打印 {person,{firstName,joe},{lastName,armstrong}}
获取值,模式匹配
Point = {point,10,15}.
{point,X,Y} = Point.
//可以打印X,Y的值. X -> 10 Y -> 15
Person = {person,{name,joe},{footsize,42},{address,beijing}}.
{_,{_,_},{_,D}{_,_}}
//获取到D -> 42
列表,类似java集合list,列表用于保存可变数量的元素。
列表头:列表内第一个元素。列表尾:除头元素的其他元素列表
Drawing = [{square,{5,5},6},{sit,{3,3},{2,6}}]
ThingsToBuy = [{apples,10},{pears,6}{milk,3}].
//添加元素
ThingsToBuyAdd = [{orangs,4},{newspaper,1}|ThingsToBuy].
//获取元素
[Buy1,Buy2|ThingsToBuyAdd2] = ThingsToBuyAdd.
字符串
字符串就是个Unicode编码的列表,字符串要用双引号
Name = “Hello”. //会显示成字符串,,想显示成编码 io:format("~w~n",[Name]).
//完全的数字列表,如果每一个数字都是Unicode 对应,就水显示成字符
[97,98,99] -> "abc"
下面这个$ 没理解
f() 命令 会让shell 忘记现有的任何绑定。
apply
调用模块里的函数,摸块名和/或函数名可以是动态计算得出的。
尽量少用apply。许多分析工具就无法 得知发生了什么
apply(erlang,atom_to_list,[hello]).
元数
指传入参数的数量,下面一个元数是1,另一个元数是2。
sum(L) -> sum(L,0).
sum([],N) -> N;
sum([H|T], N) -> sum(T, H+N).
属性
预定义属性
//设置模块名称
-module(modname).
//导入别的模块
-import().
//设置外部可调用方法
-export().
//导出模块里的所有函数,测试时会用到
-compile(Options).
//设置模块版本号
-vsn(Version).
用户定义属性
//作者
-author(Name).
//目的,描述信息
-purpose("模块功能").
使用 attrs:module_info(). 获取模块里的信息 attrs是模块名称
可以通过beam_lib:chunks 在不加载模块情况下获取数据
beam_lib:chunks("attres.beam",[attributes]).
块表达式。把块表达式的结果作为条件放入 只能单个表达式的地方(就是把这个结果代入公式)
begin
Expr1,
...,
ExprN
end
布尔值
Erlang没有单独的布尔值类型。不过原子true和false具有特殊的含义,可以用来表示布尔值。
//逻辑非 false
not true.
//逻辑与
true and false.
//逻辑或
true or false
//逻辑异或 true
(2 > 1) or (3 > 4).
字符串
着所有UTF-8可打印字符都能在源代码文件里使用,无需使用任何转义序列。
字符串其实并不存在,而是由整数列表来表示。
注释
% 这是注释
f(L) -> ["success"]. % 如果成功,注释
% f(M) -> ["sssss"]. %
动态代码载入
(这个不是热更新?)
如果在a循环调用b时重新编译了b,那么下一次a调用b时就会自动调用新版的b。
睡眠3秒
sleep() ->
receive
after 3000 -> true
end.
预处理器
Erlang模块在编译前会自动由Erlang的预处理器进行处理。预处理器会展开源文件里所有的 宏,并插入必要的包含文件。
查看预处理信息
erlc -p some_module.erl
转义序列
%% 字符编码 [97,122,65,90]
io:format("~w~n",["\a\z\A\Z"]).
%% 字符串里的八进制字符串 [83,10,1]
io:format("~w~n",["\123\12\1"]).
%%反斜杠和引号[39,34,92]
io:format("~w~n",["\'\"\\"]).
当前模块引用其他模块函数 fun x1:...
代表引用了x1模块下的square 传入1个参数的函数
double(L) -> lists:map(fun x1:square/1,L).
包含文件
-include(Filename).
-include_lib("kernel/inclub/file,hrl").
++ 和 --
%% [1,2,3,4,5,6]
[1,2,3] ++ [4,5,6].
%% [a,b,c,d,e,f,g,h,1]
[a,b,c,1,d,e,1,f,g,h,1] -- [1,1].
f("begin" ++ T) -> ...
宏
define
-define(macrol(X,Y),{a,X,Y}).
foo(A) -> ?macrol(A+10,A)
%% {a,15,5}
foo(5).
宏里的条件判断,2个宏添加一个
-module(m1).
-export([loop/1]).
-ifdef(debug_flag).
-define(DEBUG(X), io:format(X)).
-else.
-define(DEBUG(X),void).
-endif.
loop(0) -> dene;
loop(N) ->
?DEBUG(N),
loop(N-1).
模式匹配的高级用法
func1([{tag1,A,B}=Z|T]) ->
...
... f(... Z, ...)
...
func2([{tag,{one,A},B}|T]) ->
...
... f(..., {tag,{one,A},B}, ...),
... g(..., {one,A}, ...)
...
func3([{tag, {one,A}=Z1, B}= Z2|T]) ->
...
... f(...,Z2,...),
... g(...,Z1,...),
...
最高进制36
2#001010100 %%二进制
16#af6bf23 %%十六进制
#C 是ASCII字符C的整数代码: $a是97的简写,$1是49的简写
进程字典
每个Erlang进程都有一个被称为进程字典(process dictionary)的私有数据存储区域。
少用进程字典。进程字典可能会给你的程序引入不易察觉的bug,让调试变得困难。
用进程字典来保存“一次性写入”的变量。是可以接受的。
%% 清空进程字典
erase().
%% 添加常量
put(x,20).
%% 获取进程字典的指定值
get(x).
%% 获取所有进程字典的信息
get().
%% 删除性获取数据
erase(x).
比较数据类型
精确请使用 =:= 和=/=