由于工作的需要,开始学习erlang这门编程语言。下面是自己整理的一些学习笔记。
第二章 入门
“/” 永远返回浮点数, N div M 和 N rem M是用于整数除和取余数。 5 div 3 = 1, 5 rem 3 = 2.
原子是使用小写字母开头的, 使用单引号引起来的字符也是原子。
可以用$符号来表示字符的整数值。
I = $a. ----------------------->得到的结果为:97
命令f().会让shell释放所有绑定的变量。
第三章 顺序编程
-export([cost/1]). 表示导出一个cost函数,并且这个函数有一个参数。
fun()匿名函数可以带任意多个参数。
高阶函数:能够返回fun或者接受fun做为参数的函数,都被叫做高阶函数。
导出用多个函数格式:-export([total/1, sum/1]). 分号隔开
断言是一种用于强化模式匹配功能的结构,用when关键字开头表示,断言分号表示或,逗号表示与。
列表解析:记号[F(X) || X <- L] 代表由F(X)组成的列表, 其中X的值取决于列表L。
例如: L = [1, 2, 3, 4, 5].
[2 * X || X <- L].-------------->[2, 4, 6, 8, 10].
提取某个列表的字母的值:
I = $a.
记录:本质是元组, p44
-record(person, {name, age}). 其中person是记录的名字,name和age是记录中的字段名,这些名字都必须是原子。
在shell中用rd命令定义记录。 rd(person, {name, age}).
-module(person).
-export([new/2]).
-record(person, {name, age}).
new(Name, Age) ->
#person{name=Name, age=Age}.
1> person:new(ernie, 44).
{person,ernie,44}
小于或等于:2 =< 3. (ps:有些变态)
等于或大于:2 >= 3.
格式化输出的时候都要写成列表的形式(开始很不习惯啊)。
而会发现,erlang 是有两种表达方法的:
1. , 和 ;
2. andalso 和 orelse
然而,这两种表述是有区别的:
首先,假如条件是这样的 X >= N; N >= 0
,
当前半句出现异常时候,后面半句还是会执行,而且结果可能回是true;
然后,假如条件是 X >= N orelse N >= 0
,
当前半句出现异常时候,后面半句是会被跳过的,返回的结果就是异常,
而其实两种都有各自的优缺点,所以,很多情况下都是把他们两种混合起来使用,达到业务需求
第四章异常
内建的异常产生函数:
exit(Why).终止当前进程。
throw(Why).这个函数用于抛出一个调用者可能会捕获的异常。
erlang:error(Why). 这个函数用于抛出那些“崩溃错误”,致命错误。
ExceptionType是原子throw、exit、error中的一个,告诉我们异常是以什么方式产生的。
第五章顺序编程进阶
BIF内建函数。
尽量少使用apply。
可以在模块代码中添加 -compile(export_all).来导出所有的函数。
io:format("~w~n", ["\b\d\e\f"]).
引入包含文件:-include(Filename).
引入库中包含的文件:-include_lib("/kernel/include/file.hrl").
++和--只对列表有用。
在模式匹配中使用匹配操作符。
左结合:从左边开
以下划线开始的变量,消除警告。
<<2:2, 1:1>>得到的结果为<<5:3>> 从左往右开始顺序过来填充,类似于字节流。
小问题集锦:
apply功能:让你向一个模块中的某个函数传递参数并调用此函数。它与直接调用的区别在于模块和函数名可以可以动态计算。
-import(lists, [map/2]).-------------------->导入某个模块中的某个函数。
-export([a/2, b/1]). ---->从当前模块导出函数。
epp:在erlang模块被编译之前,首先会被一个名为epp的erlang预处理器进行自动处理,这个预处理器会扩展任何存在于源文件的宏,并且插入任何必需的包含文
~p是表示对一个列表不做任何修饰的打印原始结果。
函数引用: 引用一个当前模块或者外部模块所定义的函数。
fun LocaFunc/Arity. ----------------------->引用一个当前模块的函数名为LocaFunc的函数.
fun Mod:RemoteFunc/Arity. ----------------->引用Mod模块中的RemoteFunc外部函数。
包含文件:
-include(FileName). ------------------>包含扩展名为.hrl的包含文件
-include_lib("kernel/include/file.hrl").------------------>包含特定的库文件。
列表操作符++和--:
++和--是对列表进行添加和删除的中缀操作符。
宏:
宏的语法:-define(Constant, Replacement).
例如:-define(marco1(X, Y), {a, X, Y}).
?FILE 当前文件名;
?MOUDLE 当前模块名;
?LINE 当前行号。
进程字典:每个进程都有自己的私有存储数据,叫做进程字典。
短路布尔表达式:orelse和andalso,如果是用or或者and对两边的参数都会进行求值。
比较表达式:
判断是否全等最好用 =:= 。
=< 小于等于
>= 大于等于
== 等于
/= 不等于
=:= 全等于
=/= 不全等于
下划线变量:主要用于命名一个不准备使用的变量or为了方便调试。
第六章 编译并运行程序
停止erlang系统运行:
ctrl+z
erlang:halt().
q().--------------------------- 最常用,
erlang shell的内建命令, 使用help().查看。
第八章 并发编程
并发原语:
Pid = spawn(Fun). 创建一个进程
Pid ! Message 向pid进程发送消息
receive .......end 接收消息
self(),得到自己的进程号。
毫秒为单位。
p104的area_server.erl是并发编程的模型, p106的area_server_final.erl碉堡了。
一条消息处理完了就会移出进程的消息邮箱。
带超时的receive加了个after
注册进程:register
第15章 ets和dets:大量数据的存储机制