<>读书笔记---二

函数:
1.函数由若干不同匹配模式的子句组成;
2.函数不能匹配参数时,将抛出一个运行时错误.

下面举例:

-module(test1).
-export([whoischarles/1]).

whoischarles({eye,blue}) ->
'not charles';
whoischarles({hight,170}) ->
'not charles';
whoischarles({home,shandong}) ->
'not charles';
whoischarles({birthday,19830909}) ->
'yeah, i\'m charles'.
这段代码中定义了一个函数叫whoischarles,
该函数有一个参数,四个子句,参数中的匹配模式相当简单,都是由原子组成的元组.
我来分不同场景跑一下试试.

8> c(test1).
{ok,test1}
9>
9> test1:whoischarles({eye,blue}).
'not charles'
10> test1:whoischarles({birthday,19830909}).
'yeah, i\'m charles'
11> test1:whoischarles({home,hangzhou}).   
** exception error: no function clause matching
                    test1:whoischarles({home,hangzhou})
结论如下:
如果匹配正确,则返回代码中既定的结果.
如果四个子句都没有匹配,则抛出异常.
注意:四个子句要连贯的写,中间不能插入其它函数.
还需要注意的是:
函数名相同但参数不同的函数,是完全不同的函数.

上面例子中有一句代码:
-export([whoischarles/1]).
这表示本模块中,有一个对外公开访问权限的函数叫:whoischarles
且该函数有一个参数.
还有一个跟它很接近的也是导出本模块函数的声明代码:
-compile(export_all).
这句代码意思是导出本模块所有函数.
之前讲过[H|T]代表把一个列表通过模式匹配,分解成一个头元素和一个尾列表(一定要注意区分元素和列表!),
如果我们定义一个处理常见列表的方法,如:
fun([H|T]) -> ….;
再定义一个处理空列表的方法,如:
fun([]) -> null.
这样就实现了列表的迭代.

还有一种函数定义的方法,就是通过fun来实现
15> Double = fun(X) -> X*2 end.
#Fun<erl_eval.6.13229925>
这里,等号之前必须是变量,等号是个绑定的过程.

如果等号前面是原子,比如:xxx,
那将报错,
17> double = fun(X) -> X*2 end.
** exception error: no match of right hand side value #Fun<erl_eval.6.13229925>
提示是匹配出错,就是说Erlang将右边的函数去匹配左边的原子,当然无法匹配.
其实,这样我们可以联想到,绑定也就是个匹配的过程,只不过变量不是value,没有绑定也就是没有value的变量可以匹配任何value.这样理解我们就可以知道匹配和绑定其实是一回事,绑定成功就是匹配成功.

注意:在Erlang的shell中,无法这样定义函数,比如:
myname(Name) -> Name.
需要通过fun来定义函数,比如:
Myname = fun(Name) -> Name end.
再插播一个概念:
能够返回或者接受fun作为参数的函数,都被称作高阶函数.

现在我们知道fun可以定义函数,也可以实现匿名函数,
仔细想想,还有什么语言可以实现匿名函数?
是否记得javascript的函数定义跟Erlang的很像?都是有两种函数定义方法,
其中有一种就是XXX = function(params){…..};
这跟Erlang的fun实现匿名函数一样的.
再想想,是否还记得ruby也行,虽然ruby常规定义函数的方法跟Erlang和Javascript这两种定义法相差甚远,但ruby可以使用lambd或proc实现代码集的传递,比如:
myname = proc{|name|
puts name
}
然后通过myname.call(“charles”)来实现代码块的传参和调用,所以lambd和proc与Erlang和Javascript的匿名函数定义如出一辙.
这样我们可以想到,其实只要能够实现匿名函数的语言都适用于函数式语言的编程方式.

你可能感兴趣的:(JavaScript,编程,erlang,读书,Ruby)