Erlang能够说和我之前接触过的语言都大不相同,这个从它的类型定义就能够看出来。。。反正学起来以为既不熟悉,也不亲切,我估计在用Erlang写应用的时候,整个编程思路都要变一下了。不过存在便是合理的,鉴于Erlang在面向并发,轻量进程,方便的数据处理还有容错性上的巨大优点,仍是咬咬牙学吧!html
在讲述数据类型前先简单的介绍一下Erlang中的变量,Erlang中的变量和其余语言中的变量相比有三点不一样:编程
1.Erlang不对变量的类型进行定义,它能够被赋值成任何类型的值,Erlang中全部类型的值统称为一个Term。这使得编译器并不能在编译时发现数值类型的不匹配,只有在运行时发现错误,好处是不像C++同样能经过强制类型转换蒙蔽系统,形成内存泄露,也使得Erlang不像C++同样易于发现代码中的问题。不过Erlang如今已经有一套类型,函数的定义机制,能经过dialyzer来查找代码中的不匹配了。并发
2.Erlang中的变量只能被赋值一次,第二次赋值将被编译器理解为进行比较,若是值相同将返回该值,若是不一样将会抛出异常。函数
3.Erlang中的变量必须以大写字母或下划线打头,不然将不被编译器理解为变量,且大写字母打头和下划线打头的变量有些不一样的行为。ui
1.支持数字和浮点型。atom
2.浮点可表示为2.3,2.3e3,2.3e-3等类型。spa
3.支持用$char来获取字符的ASCII值code
4.支持进行2-36进制数的表示,如3#11表示4.htm
有点相似于常值。它通常都是由小写字母打头的字母组成的,若是其以大写字母打头,或者含有除字母,下划线,@以外的字符,则须要用单引号引发来表示Atom。对象
Atom比C++中的常量更方便易用,好比咱们能够直接用circle,line来表明不一样的图形类型。而不用先定义CIRCLE,LINE常量。
Atom好用可是不能滥用,由于用Atom有下面几点弊端:
1.Atom保存在atom table中,一个Atom占用4个(32bit)或8个(64bit)字节,且会持续的占用内存,不参与垃圾回收,另外其自己也有不能超过1048577个的限制。
2.Atom只能进行比较,而不能进行任何的处理操做,好比分隔,匹配等等。
Erlang中的保留字有:
after and andalso band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse query receive rem try when xor
相似于Object,不一样的是,它的长度是固定的,形式以下:
{Term1,...,TermN}
能够用模式匹配的方式轻松的获取Tuple中的某一值。
形式以下:
[Term1,...,TermN]
能够用|来链接Head和Tail,其中Head能够是任意Term,而Tail必须是List。
如[1|2]虽然能正常执行,可是却不能被length等内置函数使用。
须要注意的是:
length(1|[2,3])为3,可是
length([1,2]|3)为2
能够用模式匹配的方式依次获取List的Head。
List还支持查询式的操做,用法以下:
NewList = [Expression || GeneratorExp1, GeneratorExp2, ..., GeneratorExpN, Condition1, Condition2, ... ConditionM]
如,X取值为1或5,Y取值为6或7,咱们要找到和能被3整除的X和Y.
[{X,Y}||X<-[1,5],Y<-[6,7],(X+Y) rem 3 =:=0].
输出[{5,7}]
Bit Strings表明无类型的内存区域,表现形式为<<E1,...,En>>。
其中Ei的形式为Value 或 Value:Size 或 Value/TypeSpecifierList 或 Value:Size/TypeSpecifierList
TypeSpecifierList的形式为Type-Signedness-Endianness-unit:IntegerLiteral.
其中Type能够是integer(default),float,binary,bytes,bitstring,bits,utf8,utf16,utf32形式的
Signedness能够是signed或者unsigned(default)
Endianness能够是big(default),little,native
IntegerLiteral取值范围是1-256,这个数值用来扩展内存区域,将原来的区域扩展Size*(IntegerLiteral-1)位,默认值为1,即不进行扩展。
能够用模式匹配的方式轻松的获取内存区域中某一位置的值,用Erlang来处理数据很方便,可是不推荐使用Erlang来处理大量的数据,由于Erlang在数据处理方面比C++慢。
当Bit Strings中全部的Ei的Size都为8时,叫作Binaries。
Binaries也支持查询式的操做,实际上Binaries能查询获得List,List也能查询获得Binary。最直观的仍是举例来看一下。
1.List获得List
[2*N || N <- [1,2,3,4]].
[2,4,6,8]
2.List获得Binary,注意要写明类型或size。
<<<<(N*2):8>> || N <- [1,2,3,4]>>.
<<2,4,6,8>>
3.Binary获得List,注意<-变成了<=
[2*N || <<N>> <= <<1,2,3,4>>].
[2,4,6,8]
4.Binary获得Binary
<<<<(N*2):8>> || <<N>> <= <<1,2,3,4>>>>.
<<2,4,6,8>>
函数对象,有两种方法给函数对象赋值
1.将一个匿名函数赋值给函数对象。
匿名函数的形式以下:
fun (Pattern11,...,Pattern1N) [when GuardSeq1] -> Body1; ...; (PatternK1,...,PatternKN) [when GuardSeqK] -> BodyK end
2.将一个已经定义的函数赋值给函数对象。形式以下:
fun Name/Arity
fun Module:Name/Arity
其中Name表示函数名,Arity表示参数的个数。
String由双引号和字符串来表示,其实质是List。如"hello"等价于[$h,$e,$l,$l,$o].
两个相邻的字符串将组合成一个字符串,即"he" "llo"等价于"hello"。
也能够用Binary来表示字符串。
Record相似于Struct,Record表达式会在编译时转为tuple表达式。
1.定义Record:
-record(Name, {Field1 [= Value1],
...
FieldN [= ValueN]}).
2.新建Record:
#Name{Field1=Expr1,...,FieldK=ExprK}
其中某些Field能够省略,这时这些Field将得到默认值。
若是须要将多个Field赋同一值,能够用下面的方式:
#Name{Field1=Expr1,...,FieldK=ExprK, _=ExprL}
这时全部省略的Field都将被赋值成ExprL
3.访问Field:Expr#Name.Field
4.更新Field
Expr#Name{Field1=Expr1,...,FieldK=ExprK}
没有该类型,可是能够用true和false表明Boolean值。true和false能够正常的用在一些进行判断的场合,如:
true and false.
false or true.
true xor false.
not false.
not (true and true).
可是不能和C++中同样,当成数字来用,要牢记,在Erlang中,它是Atom值。
1.除了tuple_to_list转换成list时都会尽力转成字符串形式
atom_to_list(hello). "hello" binary_to_list(<<"hello">>). "hello" binary_to_list(<<104,101,108,108,111>>). "hello" float_to_list(7.0). "7.00000000000000000000e+00" integer_to_list(77). "77" tuple_to_list({a,b,c}). [a,b,c]
2.Number转binary都转成了字符串
integer_to_binary(77). <<"77">> float_to_binary(7.0). <<"7.00000000000000000000e+00">>
3.其余的转换
list_to_atom("hello"). hello list_to_binary("hello"). <<104,101,108,108,111>> list_to_float("7.000e+00"). 7.0 list_to_integer("77"). 77 list_to_tuple([a,b,c]). {a,b,c} term_to_binary({a,b,c}). <<131,104,3,100,0,1,97,100,0,1,98,100,0,1,99>> binary_to_term(<<131,104,3,100,0,1,97,100,0,1,98,100,0,1,99>>). {a,b,c} binary_to_integer(<<"77">>). 77 binary_to_float(<<"7.000e+00>>"). 7.0
is_atom/1 is_binary/1 is_bitstring/1 is_boolean/1 is_builtin/3 is_float/1 is_function/1 is_function/2 is_integer/1 is_list/1 is_number/1 is_pid/1 is_port/1 is_record/2 is_record/3 is_reference/1 is_tuple/1
除了上述类型以外,还有一些特别的类型,如reference(),pid(),port()等将在之后介绍。
参见:http://www.erlang.org/doc/reference_manual/data_types.html