1。如果guard发生错误,不会报错,只会报错!
结果是:错误
计算受保护表达式中t(原子)的长度时会出现错误。应该会崩溃,但是因为在protected表达式中,protected表达式的计算默认在出错后结束并返回false。这就是受保护的表达式不接受复杂函数的原因。 ,这也是只能使用erlang的bif来完成的原因之一。
2。如果尝试catch时不写catch类型,则默认是throw类型!
结果:
所以最好明确一点:Catch throw:T –> { throw,T};错误:T –> {错误,T};退出:T –> {退出,T} 结束。
3。在保护表达式中使用 erlang:length/1 时要小心! (遍历列表,时间长度是可变的)
提示:如果想判断List是否为非空List,可以使用case List of [_|_] –> do_something(); _ –> 完成。
4。 ++只是lists:append/2的别名:如果你想使用它,一定要使用ShortList++LongList! (可以记为长与短短与长的反义词...每次使用都会条件反射性地思考)
这是反转列表的最低效的方法。由于 ++ 运算符复制其左操作数,因此结果将被一次又一次地复制......导致二次复杂度。
这是反转列表的最低效的方法。 “++”将复制左侧的元素。这将导致多个副本,从而导致复杂度平方。
但另一方面:以下用法也可以:
这不是一个非常糟糕的尝试。每个列表元素仅复制一次。递增的 Acc 位于 ++ 的右侧。不会每次都复制
当然,最佳做法仍然是以下:
这个比上面的效率高一点。您根本不需要创建列表元素,只需直接复制它即可(或者:如果编译器不将 [H]++Acc 重写为 [H|Acc] ,那会更有效)。
5。 receive 和 case 之间有很大的区别,尽管它们的写法类似:
结果:
从上面可以看到:
5.1 case 如果没有匹配就会出错;
5.1 接收在没有匹配消息时将阻塞。只要邮箱中没有匹配的邮件,就会在等待期间挂起。只有当有新消息到达时它才会被唤醒。每次执行时,recieve都会先检查最旧的消息(位于队列的头部),尝试按照case表达式中的方式进行匹配,如果没有找到,则继续下一条消息,如果当前匹配成功,并且保护为真(如果有),则该消息将从邮箱中删除,并且该子句的相应文本将被执行。如果没有找到合适的消息,就会等待直到超时(如果有,则在Times之后)。
6。当erl使用-noshell –noinput启动节点时,我看不到它,也无法输入它。我该如何调试它?使用-remsh参数
这里的陷阱是:
6.1 在远程节点上调用q(),两个节点都会退出!它是可怕的。最好重写 user_default.erl 中的 q() 函数,使其不执行 init: stop()。
6.2 window下使用werl代替erl;
6.3 erl 支持自定义参数。例如,如果您编写 erl –rmsh test,则不会出现错误。如果一不小心写错了,要查很久……
提示: 已经设置了两个节点A和B。如果想用A控制B,可以在A中使用 Ctrl+G r NodeA j 2 操作。具体参见:学习一些erlang远程shell。
7。如果有一个像这样从不知名的地方传递过来的ArgList:“[test1,test2,test3]”,怎么用它来动态执行呢?
场景:了解方法调用的方式:Method使用erlang:apply(Module,Method,ArgList)来调用产生结果。此时ArgList不符合格式:
上面合适的List中的所有参数都是绑定的:如果有像Test1这样的变量,我没有尝试过,也没有遇到这样的需求
可以参考
8。 erl启动参数可以自己定义:如
8.1 不要将参数定义为字符串:例如“hello world”
8.2 如果这用于启动应用程序,则不要期望使用此自定义参数。使用config来定义它
应用程序通常不应使用命令行标志进行配置,而应使用应用程序环境。有关详细信息,请参阅设计原则章节中的配置应用程序
9。使用RPC时,一定要记住你是分布式的,并且时刻注意你处于哪个进程!
例如:将rpc:call放在循环内部和外部会得到不同的效率反馈。以下示例的结果是等效的,但第一个将发出多次调用,而第二个将仅发出一次调用。
同样,你可以自己更改它:[gen_server:call(Pid,{func,Fun})||Fun<- FunList]。
简而言之,如果你可以发送一次消息并处理它,就不要发送多次。 10 不要构造非常大的术语(或您无法控制大小的术语)。 具体来说,如果要遍历ets中的所有元素,使用ets:tab2list/1得到的结果可能会很大。我应该怎么办?