Erlang development experience: Anti-pitfall guide and erlang experience
This problem occurs in any language, and so does erlang. Here we will sort out some of my problems to avoid further difficulties. To be honest, the title of "anti-pitfall Guide" is somewhat unconventional, but we still hope to pay attention to it and avoid repeating these issues in actual development.
'--' Operation
1> [1, 2, 3, 4] -- [1] -- [2]. [2, 3, 4] is a classic erlang problem. This is counted from the end. Calculate [1] -- [2] First, get [1], get [1], get [1, 2, 3, 4] --, and finally get [2, 3, 3, 4] If ++ is the same, it starts from the back, but ++ calculates the same result from the front or back. 2> [,] -- [2]. [, 2] in this case, note that only the first element is subtracted.
Erlang: function_exported
This interface is used to check whether the module functions are exported. However, if the module has not been loaded, the return value of this function is false3> erlang: function_exported (odbc, start, 0 ). false4> odbc: start (). ok5> erlang: function_exported (odbc, start, 0 ). true I have discussed this problem before. For the solution, see here.
Erlang: list_to_binary
If the parameter is a multi-layer nested structure, it will be flat. Using binary_to_list cannot be converted to the original data, which is irreversible. 6> list_to_binary ([1, 2, [3, 4], 5]). <, 5> to be reversible, use erlang: term_to_binary7> binary_to_term (term_to_binary ([, [], 5]). [1, 2, 3, 4], 5]
Try... catch
Try1 (ErrType)-> try case ErrType of error-> erlang: error (error); exit-> erlang: exit (exit); throw-> erlang: throw (throw) end catch Err-> Err end. |
8> test: try1 (error ). ** exception error: error in function test: try1/1 (test. erl, line 7) 9> test: try1 (exit ). ** exception exit: exit in function test: try1/1 (test. erl, line 8) 10> test: try1 (throw ). only the results above throw can be matched. If you want to match all the results, you need to rewrite this function:
Try1 (ErrType)-> try case ErrType of error-> erlang: error (error); exit-> erlang: exit (exit); throw-> erlang: throw (throw) end catch _: Err-> Err end. |
Assertion (guard)
Check (A) when length (A)> 9-> error; check (_)-> OK. |
Check the list length, but what if the input data is not a list? 11> test: check (hack). OK in guard mode, the code that originally throws an exception will not report an error, but end the current calculation and return false. By the way, the following situations are described:
Check1 (A) when length (A)> 9; true-> error; check1 (_)-> OK. check2 (A) when length (A)> 9 orelse true-> error; check2 (_)-> OK. check3 (A) when length (A)> 9, true-> error; check3 (_)-> OK. check4 (A) when length (A)> 9 andalso true-> error; check4 (_)-> OK. |
12> test: check1 (hack ). error13> test: check2 (hack ). ok14> test: check3 (hack ). ok15> test: check4 (hack ). OK, so we can see that there is a difference between orelse and.
Io_lib: char_list
The running result of this function in R15 and R16 may be the opposite.
Under R15: Eshell V5.9.3.1 (abort with ^ G) 1> io_lib: char_list ([20100,]). false R16: Eshell V5.10.1 (abort with ^ G) 1> io_lib: char_list ([20100,]). true |
The result is the opposite. You can imagine that if you write this code, you may have a problem running another version. The erlang version transition is still a bit extensive.
Gen_server
Gen_server uses noconnect to send messages across nodes. This is the correct choice. You can refer to this Article. However, gen_server: cast may have problems. The following is the implementation code of cast:
Do_cast (Dest, Request)-> do_send (Dest, cast_msg (Request), OK. do_send (Dest, Msg)-> case catch erlang: send (Dest, Msg, [noconnect]) of noconnect-> spawn (erlang, send, [Dest, Msg]); other-> Other end. |
When the connection fails, cast starts a new process to send messages. That's all. Without noconnect, the message will be sent as much as possible. It is not difficult here, But gen_server is generally not aware of this problem. When the network is not ideal, many processes will be added, and the maximum number of processes is limited. In addition, messages cannot be sent out, but are still accumulated in the memory.
Comparison of Different Types of data
Different types of data can also be compared in size
16> hack> 1. true17> []> 1. true18> []> {a, B, c}. true |
Comparison formula: number <atom <reference <fun <port <pid <tuple <list <bit string
System Restrictions
These are a bit old-fashioned, but you should pay attention to them during development. 1. mnesia or dets has 2 GB limit (cannot be customized) 2. the maximum number of ets tables is 1400 by default (customized by ERL_MAX_ETS_TABLES). 3. the maximum number of atoms is 1048576 by default (available + t custom) 4. the maximum number of processes is 32768 by default (available + P customization, range: 1024-134217727. the maximum number of port/file handles is 16384 by default (available + Q customization, range: 1024-134217727)
Reference: http://blog.csdn.net/mycwq/article/details/43775285
Finally, this title is indeed somewhat unconventional.