《Erlang程序设计中文版》-读书笔记

读《Erlang程序设计中文版》,只记录自己容易忘记、还不懂、或者需要注意的内容。

Chapter 2 入门

  1. 变量可以16进制和32进制记号:16#cafe、32#sugar
  2. 除号 ”/“ :永远返回浮点数。整除:div  和 求余:rem(都只能用于整数)
  3. 原子(item)一般以小写字母开头:monday。但用了单引号,就可以任意定义:‘Monday’
  4. “=”用于模式匹配,对于未绑定变量,才是赋值。“=”右边,不能有未绑定变量
  5. 字符串就是列表:"abc" = [97,98,99] ,shell下会默认把都是可打印字符的列表,以字符串形式显示。"$"用于字符前,可以获得对应的ASCII的整数值: $a (97)
  6. 命令f():让shell释放所有变量

Chapter 3 顺序型编程

  1. 同名不同目的函数,一般用于辅助函数(传默认值)
  2. 匿名函数不同子句,不要重复fun
    Fun = fun({case1,X})->ok;
             ({case2,X})->error end.
  3. lists标准库常用函数:
  • lists:map(F,L):返回映射后的列表
  • lists:filter(P,L):返回列表,元素满足函数P返回值为true
  • lists:member(X,L):返回true
  • lists:sum(L):对列表各元素求和
  • lists:seq(1,N):返回1到N的整数列表
  • lists:reverse(L)
  • lists:foreach(fun,L) 返回ok,类似map

      4.  记录(record)匹配,不需要列出所有项

-record(todo,{status=undefine,who,text}).
...
X = #todo{}.                        %%新建,可以不全指定
X1 = X#todo{status=ok,who="Nick"}.  %%更新部分字段
#todo{status=Sta}=X1.               %%提取部分字段,不用列出所有项。可用于函数的参数提取
      5.  rf(记录名):释放记录定义,让记录变成元组

Chapter 4 异常
      1.  异常的发生原因:内部错误(模式匹配失败,BIF调用失败:atom_to_list(32)),显式/主动抛错(throw(Exception),exit(Exce),erlang:error(Exce))
      2.  try-catch 格式
try Sequences of                      try Sequences    %%省略格式
    Result1->...                      catch
    Result2->...                          Catch1->...
catch                                 end
    Catch1->...  %%默认throw型
    exit:Catch2->...
    error:Catch3->...
after
    ...
end
      3.  catch中,_:_->捕获所有异常,_->只捕获throw的。用_:Error->error_logger:error_msg("{~p,~p~n}",[Error,erlang:get_stacktrace()])输出栈跟踪信息,获取报错行数

Chapter 5 顺序型编程进阶
      1.  BIF操纵二进制数据
  • @spec list_to_binary(L)->Bin                     L的元素必须是0~255的整数,二进制数或另一个L。不能list_to_binary([a,b,c]).
  • @spec split_binary(Bin,Pos)->{Bin1,Bin2}
  • @spec term_to_binary(Term)->BIn
  • @spec Binary_to_term(Bin)->Term
  • size(Bin)
      2.  比特语法表达式:<<E1,E2>> 
           Ei格式:
  • Value       %%默认Type=integer,Unit=1,End=big,Sign=unsigned
  • Value:Size
  • Value/TypeSpecifierList
  • Value:Size/TypeSpecifierList
      3.  apply(Mod,Fun.[Arg1,..ArgN]):可以动态调用函数
      4.  beam_lib:chunks可以来提取属性。
      5.  begin..end  块语句,可以合并成相当于一个单个语句
      6.  函数值是两个原子值中的一个,用true/false做为返回值,就可以通用、结合其他标准库函数
      7.  fun Mod:RemoeFun/Arity 和 fun LocalFun/Arity 动态引用函数: lists:map(fun square/1,L).  %%square/1 为内部函数
      8.  --操作符,依次删,没有就不删:[1,2,3,3]--[3]只删第一个3
      9.  宏定义,取消宏定义:-undef(MACRONAME) .   
-ifdef(MACRONAME).
-define(Fun(X),X*2).
-else
-define(Fun(X),X*3).
-endif.
      10. 模式中使用匹配操作符:fun( [ {tag1,{one,A} = Z1,B} = Z2 | T] )->函数中可以直接使用Z1,Z2了,避免两次创建
      11. 引用erlang:make_ref():还不知道怎么用
      12. 短路布尔表达式:andelse、orelse
      *13. 比特高级语法示例,还没看

Chapter 6 编译并运行程序
      1.  .erlang在home目录下,里面可以设置加载目录:code:add_patha(FilePath)。shell下,用init:get_argument(home).可以获取home目录位置
      2.  用命令行编译运行:
erlc -o ebin src/*.erl   %%编译到ebin下
erlc hello.erl           %%直接编译到当前目录
erl -noshell -pa ebin -s hello start 25 24 -s init stop        %%带参数运行hello:start([25,24])
erl -noshell -pa ebin -s hello                                 %%没有函数名,默认启动hello:start()

hello.erl
start()->
    ok.

main([A,B])->
    io:format("~p~n",[A]),
    init:stop().

     3.  escript脚本运行 可以不要编译就运行,不懂现在,还有eval不知道怎么运行多个函数
     4.  shell下输入,webtool:start(),去看错误日志
     5.  shell中的编辑命令,^t:颠倒两个字母,tab键:提示
     6.  写sh脚本自动运行hello.erl,运行前,先给权限:chmod u+x hello.sh,再./hello.sh
#!/bin/sh

erl -noshell -pa ebin -s start\
    -s init stop
     *7. makefile还没看

Chapter 8 并发编程
      1.  Pid ! Message 返回值是Message,所以可以Pid1 ! Pid2 ! Msg 
      2.  服务器和客户端,在erlang中,都看成是进程,只是扮演角色不同
      3.  Pid = spawn(fun Mod:fun/Arty) 或者 Pid = spawn(fun()->Mod:fun(Args) end)
      4.  statistics(runtime):运行代码Cpu占用、花费的时间,statistics(wall_clock):真实消耗时间(cpu上消耗+等待的时间),单位微秒
statistics(runtime),
statistics(wall_clock),
...
{_,Time1} = statistics(runtime),
{_,Time2} = statistics(wall_clock)
      5.  receive语句中after子句执行前,先要匹配一下邮箱。引申出优先匹配和清空邮箱的功能。infinity:无限等待,这样就可以由外部指定是否设置超时了。
      6.  send、receive的实质:把消息发到一个进程中的邮箱中,从本进程的邮箱中删除消息。
           receive消息,一条条匹配,匹配不到,保存到一个队列中,一旦匹配到,释放队列到邮箱。一条都没匹配到,新消息来就先匹配新消息。
      7.  register(atomName,Pid),registered()->[],unregister(atomName),whereis(atomName)->Pid | undefined
      8.  定时操作
tick(Time,Fun)->
    receive
        stop->
            void
    after Time->
            Fun(),
            tick(Time,Fun)
    end.

 Chapter 9 并发编程中的错误处理

      1.  link(Pid):进程相互之间建立链接,就会彼此监视。可以通过process_flag(trap_exit,true),设置当前进程为捕获进程,这样就不会自动退出了。
      2.  进程消亡:结束,exit(Reason),出错,都会发送{'Exit',Pid,Reason}给链接进程。
      3.  Pid1向其他进程发送exit:exit(Pid2,Reason),Pid2会收到{'Exit',Pid1,Reason}(trap的话),Pid1装死
      4.  exit(kill)无法捕获
      5.  spawn_link(Fun)->Pid,spawn和link同时完成
      *6.  9.4.2捕获退出信号(进阶篇)还没看
 
 Chapter 10 分布式编程
      1.  rpc:call(Node,Mod,Fun,[Arg1,Arg2]),调用远程节点上的函数
      2.  net_adm:ping(Node) -> pong  |  pang  disconnect_node(Node)->bool() | ignored
      3.  分布式的核心就是节点,1个节点就是1个独立进程集的虚拟机
      4.  jj


 Chapter 14 套接字编程
      1. 客户端    gen_tcp:connect(Host,Port,[binary,{packet,0}]).->{ok,Socket} | {error,Reason}
                         gen_tcp:send(Socket,"msg...").->ok | {error,Reason}
                         receive时,{tcp,Socket,Bin} 或者 {tcp_closed,Socket}
      2. 服务端    gen_tcp:listen(Port,[binary,{packet,4},{reuseaddr,true},{active,true}])->{ok,ListenSocket} | {error,Reason}
                         gen_tcp:accept(ListenSocket) -> {ok,Socket} | {error,Reason}
                         gen_tcp:close(Socket) -> ok
                         receive时,同客户端
      3. 套接字的三种打开类型:
                         {active,true}:直接receive end接受,客户端发的太快会淹没消息缓冲区,服务端崩溃
                         {active,false}:需要gen_recv(Socket,N) -> {ok,Data} | {error,Reason}接受指定字节,但会阻塞客户端,且只对一个套接字有效(待验证)
                         {active,once}:需要手动inet:setopts(Socket,[{active,once}])
      4. 套接字来源: inet:peername(Socket) -> {ok,{Ip_Address,Port}} | {error,Reason}
      5. 套接字出错,gen_accept(Listen)的进程崩溃

 Chapter 15 ETS和DETS
      1. 表的类型:set(后者冲前者)、ordered set、bag(不允许完全相同)、duplicate bag
      2. ets:new(TableName,[public,named_table,{read_concurrency,true} |,{wirte_concurrency,true}]),ets:info(Tab,size) -> integer().
      3. ets:match(Tab,Pattern) -> [Match].和 ets:select(Tab,MatchSpec) -> [Match].
ets:new(t ,[named_table]).
ets:insert(t,[{1,2},{2,b},{3,c},{4,d}].
MS = ets:fun2ms( fun({X,Y}) -> when (X>1) or (X<5) -> {Y} end).
> [{{'$1','$2'},[{'or',{'>','$1',1},{'<','$1',5}}],[{{'$2'}}]}]
ets:select(t,MS).
> [{2},{b},{c},{d}]. 
      4.  aa





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值