• [Erlang11] 那些经历过的Erlang小坑11-20


    11.每次重装系统时都会重新安装Erlang,Ubuntu安装sh秒杀一切.

         https://gist.github.com/zhongwencool/11174620

    12. Erlang Shell隐藏的小技巧:

        f(). %%把所有绑定变量释放掉
        f(Val). %%把Val变量释放掉
        v(Line). %%把Line行函数重新执行一次
        v(-1). %%把前一行的函数重新执行一次
        rr(Module).%%把Module中的Record加载到Shell中,【超有用】
        rr("*/*"). %%把在这个子目录下的所有Module里面的Record给加载到Shell里面
        rp(Expression).%%把Expression的全部元素给打印到shell里面【超有用】
         rl(). %%列出所有已定义过的Record.rf(RecordName).%%不加载名为RecordName的Record
         %%如果你的code加了debug_info信息【compile:file(Module,[debug_info])】你可以这样看源代码
        {ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(Beam,[abstract_code]),
        io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).

    13. Erlang中有很多不可逆函数:比如 binary_to_list/1 , list_to_binary/1

      > binary_to_list(list_to_binary([ <<1,2>>,<<3,4>>])).
        [1,2,3,4]

        这个坑有点深,踩过才知道!这还有个和binary一起的小Tip:

       > <<"xyz","ets","bt">> =:= <<"xyzetsbt">>.           
         true

        binary居然是等价的。

    14.在保护式里面 ,等价于andalso ;等价于orelse------[但是:不是完全相同,原因如下]

       %%相同点:
    right_age(X) when X >= 16, X =< 104 -> %% X>=16 andalso X =< 104 true; right_age(_) –> false.

         不同点:

        %%当Condition1异常出错时,还会去判断Condtion2,如果使用orelse则会直接返回false
        func() when Condition1 ; Condition2 –> 
          ok;
        func() –>
          error.

         可以和http://www.cnblogs.com/zhongwencool/p/3712909.html 第一条对比一下,理解更深哦。

    15.如果你想在实践中使用二叉树,请看gb_tree.erl,不要再造不必要的轮子啦,【不过可以考虑用来做练习】

    16. 在try catch 的异常处理中禁止使用尾递归:

          因为在这个异常处理部分有一个保护机制,Erlang绝对相信异常处理是正常的,如果你在这里面使用尾递归,会出现以下情况:

        1) 尾递归变死循环啦【项目实践中可能会发生的】;
        2) 非常多的进程进入了这个异常中,这个尾递归处理的东西又非常复杂,VM运行长久后,block大量的进程和消耗内存

          这样的结果是:内存耗尽或程序特别慢,关键你还是查找不到最后的crash的原因。

          所以推荐:异常处理中只使用必要且简单的处理就行了

    17. 如果你想在Erlang中 kill一个进程:找到Pid后,exit(Pid,Reasno).【效果和kill一样啦】

          大部分情况不会起作用!!!!!因为在项目里面你的进程如果合规范都是在监控树下的,如果被exit/2后还会被监控树自动重启啦,所以你要先把进程移除监控树!!!

        supervisor:terminate_child(SupPid,Pid), 
        supervisor: delete_child(SupPid,Pid).

    18. 2个进程可以双向连接和单向连接:

         双向: link(Pid1,Pid2). 重复调用效果一样,也就是说对同2个进程无论调用多少次link,只要使用一次unlink(Pid1,Pid2)就解除连接

         单向:erlang:monitor/2   erlang: demonitor/1

    19. receive  after Time

          这个Time最大值是50*24*60*60*1000,当时间大于50天时,就会报错:

          所以要把Time拆成小于最大值的列表:

      normalize(Time) –>
          Limit = 49*24*60*60,
          [Time rem Limit | lists:duplicate(Time div Limit, Limit)].

          然后如果时间列表不为空就不断减少列表并等待直到列表为空:

      loop([T|Next]}) –>
         receive
            {Server, Ref, cancel} –>
               Server ! {Ref, ok}
            after T*1000 –>
               if Next =:= [] –>
                   Server ! {done, S#state.name};
                  Next =/= [] –>
                  loop(Next})
               end
         end.

    20. gen_server里面的handle_call/3 和handle_cast/2返回值都可以加个Timeout时间。

         如果这个时间内没有处理完就会发出一个timeout信息:由handle_info处理,具体可见:http://www.cnblogs.com/zhongwencool/p/erlang_timer.html 里面的方法二。

  • 相关阅读:
    数据表格
    数据表格
    数据表格
    布局
    表单
    表单
    Java知识点梳理——继承
    Java知识点梳理——抽象类和接口
    面试心得与总结—BAT、网易、蘑菇街
    Java知识点梳理——多态
  • 原文地址:https://www.cnblogs.com/zhongwencool/p/erl_tip.html
Copyright © 2020-2023  润新知