Erlang 学习笔记(二)
guibin.beijing@gmail.com
[size=medium]1.5 Erlang的数据类型[/size]
[b][u]变量(variables):[/u][/b]
从[url=927861]Erlang 学习笔记(一)[/url]中的代码中的double函数定义发现,其参数为X,而且是大写的,这就是Erlang对变量定义的要求。
Erlang中变量必须以大写字母开头,比如Number,ShoeSize,Age等。如果不是以大写字母开头,编译时会报错。
[b][u]Atoms:[/u][/b]
Erlang中另外一种数据类型叫Atoms。Atoms以小写字母开头,仅仅表示名字而已,没有其他意义,变量可以存储数据,而Atoms则不能存值数据。比如tut2中
[quote]-module(tut2).
-export([convert/2]).
convert(M, inch) ->
M / 2.54;
convert(N, centimeter) ->
N * 2.54.
[/quote]
convert函数将英寸和厘米相互转换。在这个convert函数定义中使用的"inch"和"centimeter"就是Atoms,M和N是变量。Atoms在这里相当于用来区分两个函数的用途,起到标记的作用。
在convert inch的定义结束时,使用了";"而不是".",这表示分号之后还有属于该函数的代码。
编译和运行结果如下:
[quote]5> c(tut2).
{ok,tut2}
6> tut2:convert(20, inch).
7.874015748031496
7> tut2:convert(20, centimeter).
50.8
[/quote]
[b][u]元组(Tuples):[/u][/b]
Erlang使用Tuple将一组相关的数据放在一起,使得更易于理解。Tuple用大括号“{}”将元素包围起来。回忆一下,Scala中也有Tuple,其意义和Erlang的一样,区别是使用小括号“()”。
比如tut3:
[quote]-module(tut3).
-export([convert_length/1]).
convert_length({centimeter, X}) ->
{inch, X / 2.54};
convert_length({inch, Y}) ->
{centimeter, Y * 2.54}.
[/quote]
编译和运行结果如下:
[quote]10> tut2:convert(20, inch).
7.874015748031496
11> tut2:convert(20, centimeter).
50.8
12> tut3:convert_length({inch, 20}).
{centimeter,50.8}
13> tut3:convert_length({centimeter, 20}).
{inch,7.874015748031496}
14> tut3:convert_length(tut3:convert_length({centimeter, 20})).
{centimeter,20.0}
[/quote]
注意上面14行是如何工作的,首先将20厘米转换成英寸,然后在转换回厘米,结果还是原来的20厘米。函数的返回值作为外层函数的输入参数。
截止目前为止,我们看到的元组都只有两部分,实际上元组可以有任一多部分组成。比如:
[quote]{moscow, {c, -10}}
{cape_town, {f, 70}}
{paris, {f, 28}}
[/quote]
[b][u]列表(Lists):[/u][/b]
列表就是用“[]”将多个元素括起来,元素之间用逗号“,”隔开。比如:
[quote][{moscow, {c, -10}}, {cape_town, {f, 70}}, {stockholm, {c, -4}}, {paris, {f, 28}},
{london, {f, 36}}]
[/quote]
List一般如果比较长,一行写不下的话,则Erlang允许将代码在任何“合理”的地方断开,比如,只要不在atoms,integers等中间断开就可以。
另外可以使用"|"来查找List中特定位置上的元素,请看如下的例子:
[quote]20> [First | Rest] = [1, 2, 3, 4].
[1,2,3,4]
21> First.
1
22> Rest.
[2,3,4]
[/quote]
这和Scala中的模式匹配非常类似。First匹配上了第一个元素,剩余的全部元素匹配给Rest。
[quote]23> [First2, Second2 | Rest2] = [1, 2, 3, 4, 5, 6, 7, 8].
[1,2,3,4,5,6,7,8]
24> First2.
1
25> Second2.
2
26> Rest2.
[3,4,5,6,7,8]
27> [/quote]
使用"|"获取List中前两个元素,剩余的赋给"|"后面的元素。如果List长度比要匹配的少一个,则返回空List。比如:
[quote]4> [One, Two, Three | Last] = [1, 2, 3].
[1,2,3]
5> Last.
[]
6> Three.
3
[/quote]
如果List的长度比要匹配的少多个,则会抛异常:
[quote]5> [One, Two, Three | Last] = [1, 2].
** exception error: no match of right hand side value [1,2][/quote]
看一个使用List的综合例子。该例子list_length获取List的长度:
[quote]-module(tut4).
-export([list_length/1]).
list_length([]) ->
0;
list_length([First | Rest]) ->
1 + list_length(Rest).
[/quote]
编译和运行:
[quote]10> c(tut4).
./tut4.erl:6: Warning: variable 'First' is unused
{ok,tut4}
11> tut4:list_length([]).
0
12> tut4:list_length([1, 2, 3, 4]).
4
13> tut4:list_length(["Hello", "Hi"]).
2
[/quote]
看到编译时提示的警告,说First定义了但是没有使用,跟Scala一样,我们可以用占位符“_”代替First,然后再次编译运行就没问题了。代码如下:
[quote]-module(tut4).
-export([list_length/1]).
list_length([]) ->
0;
list_length([_ | Rest]) ->
1 + list_length(Rest).
[/quote]
[b][u]字符串(String):[/u][/b]
Erlang没有String数据类型,而字符串可以给ASCII码代替。因此[97, 98, 99]和“abc”相等。比如:
[quote]23> [97, 98, 99].
"abc"
[/quote]
Guibin
guibin.beijing@gmail.com
[size=medium]1.5 Erlang的数据类型[/size]
[b][u]变量(variables):[/u][/b]
从[url=927861]Erlang 学习笔记(一)[/url]中的代码中的double函数定义发现,其参数为X,而且是大写的,这就是Erlang对变量定义的要求。
Erlang中变量必须以大写字母开头,比如Number,ShoeSize,Age等。如果不是以大写字母开头,编译时会报错。
[b][u]Atoms:[/u][/b]
Erlang中另外一种数据类型叫Atoms。Atoms以小写字母开头,仅仅表示名字而已,没有其他意义,变量可以存储数据,而Atoms则不能存值数据。比如tut2中
[quote]-module(tut2).
-export([convert/2]).
convert(M, inch) ->
M / 2.54;
convert(N, centimeter) ->
N * 2.54.
[/quote]
convert函数将英寸和厘米相互转换。在这个convert函数定义中使用的"inch"和"centimeter"就是Atoms,M和N是变量。Atoms在这里相当于用来区分两个函数的用途,起到标记的作用。
在convert inch的定义结束时,使用了";"而不是".",这表示分号之后还有属于该函数的代码。
编译和运行结果如下:
[quote]5> c(tut2).
{ok,tut2}
6> tut2:convert(20, inch).
7.874015748031496
7> tut2:convert(20, centimeter).
50.8
[/quote]
[b][u]元组(Tuples):[/u][/b]
Erlang使用Tuple将一组相关的数据放在一起,使得更易于理解。Tuple用大括号“{}”将元素包围起来。回忆一下,Scala中也有Tuple,其意义和Erlang的一样,区别是使用小括号“()”。
比如tut3:
[quote]-module(tut3).
-export([convert_length/1]).
convert_length({centimeter, X}) ->
{inch, X / 2.54};
convert_length({inch, Y}) ->
{centimeter, Y * 2.54}.
[/quote]
编译和运行结果如下:
[quote]10> tut2:convert(20, inch).
7.874015748031496
11> tut2:convert(20, centimeter).
50.8
12> tut3:convert_length({inch, 20}).
{centimeter,50.8}
13> tut3:convert_length({centimeter, 20}).
{inch,7.874015748031496}
14> tut3:convert_length(tut3:convert_length({centimeter, 20})).
{centimeter,20.0}
[/quote]
注意上面14行是如何工作的,首先将20厘米转换成英寸,然后在转换回厘米,结果还是原来的20厘米。函数的返回值作为外层函数的输入参数。
截止目前为止,我们看到的元组都只有两部分,实际上元组可以有任一多部分组成。比如:
[quote]{moscow, {c, -10}}
{cape_town, {f, 70}}
{paris, {f, 28}}
[/quote]
[b][u]列表(Lists):[/u][/b]
列表就是用“[]”将多个元素括起来,元素之间用逗号“,”隔开。比如:
[quote][{moscow, {c, -10}}, {cape_town, {f, 70}}, {stockholm, {c, -4}}, {paris, {f, 28}},
{london, {f, 36}}]
[/quote]
List一般如果比较长,一行写不下的话,则Erlang允许将代码在任何“合理”的地方断开,比如,只要不在atoms,integers等中间断开就可以。
另外可以使用"|"来查找List中特定位置上的元素,请看如下的例子:
[quote]20> [First | Rest] = [1, 2, 3, 4].
[1,2,3,4]
21> First.
1
22> Rest.
[2,3,4]
[/quote]
这和Scala中的模式匹配非常类似。First匹配上了第一个元素,剩余的全部元素匹配给Rest。
[quote]23> [First2, Second2 | Rest2] = [1, 2, 3, 4, 5, 6, 7, 8].
[1,2,3,4,5,6,7,8]
24> First2.
1
25> Second2.
2
26> Rest2.
[3,4,5,6,7,8]
27> [/quote]
使用"|"获取List中前两个元素,剩余的赋给"|"后面的元素。如果List长度比要匹配的少一个,则返回空List。比如:
[quote]4> [One, Two, Three | Last] = [1, 2, 3].
[1,2,3]
5> Last.
[]
6> Three.
3
[/quote]
如果List的长度比要匹配的少多个,则会抛异常:
[quote]5> [One, Two, Three | Last] = [1, 2].
** exception error: no match of right hand side value [1,2][/quote]
看一个使用List的综合例子。该例子list_length获取List的长度:
[quote]-module(tut4).
-export([list_length/1]).
list_length([]) ->
0;
list_length([First | Rest]) ->
1 + list_length(Rest).
[/quote]
编译和运行:
[quote]10> c(tut4).
./tut4.erl:6: Warning: variable 'First' is unused
{ok,tut4}
11> tut4:list_length([]).
0
12> tut4:list_length([1, 2, 3, 4]).
4
13> tut4:list_length(["Hello", "Hi"]).
2
[/quote]
看到编译时提示的警告,说First定义了但是没有使用,跟Scala一样,我们可以用占位符“_”代替First,然后再次编译运行就没问题了。代码如下:
[quote]-module(tut4).
-export([list_length/1]).
list_length([]) ->
0;
list_length([_ | Rest]) ->
1 + list_length(Rest).
[/quote]
[b][u]字符串(String):[/u][/b]
Erlang没有String数据类型,而字符串可以给ASCII码代替。因此[97, 98, 99]和“abc”相等。比如:
[quote]23> [97, 98, 99].
"abc"
[/quote]
Guibin