zoukankan      html  css  js  c++  java
  • Erlang学习记录(二)——基本数据类型

    Erlang可以说和我以前接触过的语言都大不相同,这个从它的类型定义就可以看出来。。。反正学起来觉得既不熟悉,也不亲切,我估计在用Erlang写应用的时候,整个编程思路都要变一下了。不过存在即是合理的,鉴于Erlang在面向并发,轻量进程,方便的数据处理还有容错性上的巨大优势,还是咬咬牙学吧!

    在讲述数据类型前先简单的介绍一下Erlang中的变量,Erlang中的变量和其他语言中的变量相比有三点不同:

    1.Erlang不对变量的类型进行定义,它可以被赋值成任何类型的值,Erlang中所有类型的值统称为一个Term。这使得编译器并不能在编译时发现数值类型的不匹配,只有在运行时发现错误,好处是不像C++一样能通过强制类型转换蒙蔽系统,造成内存泄露,也使得Erlang不像C++一样易于发现代码中的问题。不过Erlang现在已经有一套类型,函数的定义机制,能通过dialyzer来查找代码中的不匹配了。

    2.Erlang中的变量只能被赋值一次,第二次赋值将被编译器理解为进行比较,如果值相同将返回该值,如果不同将会抛出异常。

    3.Erlang中的变量必须以大写字母或下划线打头,否则将不被编译器理解为变量,且大写字母打头和下划线打头的变量有些不同的行为。

    一.Number

    1.支持数字和浮点型。

    2.浮点可表示为2.3,2.3e3,2.3e-3等类型。

    3.支持用$char来获取字符的ASCII值

    4.支持进行2-36进制数的表示,如3#11表示4.

    二.Atom

    有点类似于常值。它一般都是由小写字母打头的字母组成的,如果其以大写字母打头,或者含有除字母,下划线,@之外的字符,则需要用单引号引起来表示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

    三.Tuple

    类似于Object,不同的是,它的长度是固定的,形式如下:

    {Term1,...,TermN}

    可以用模式匹配的方式轻松的获取Tuple中的某一值。

    四.List

    形式如下:

    [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

    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>>

    六.Fun

    函数对象,有两种方法给函数对象赋值

    1.将一个匿名函数赋值给函数对象。

    匿名函数的形式如下:

    fun
        (Pattern11,...,Pattern1N) [when GuardSeq1] ->
            Body1;
        ...;
        (PatternK1,...,PatternKN) [when GuardSeqK] ->
            BodyK
    end

    2.将一个已经定义的函数赋值给函数对象。形式如下:

    fun Name/Arity
    fun Module:Name/Arity

    其中Name表示函数名,Arity表示参数的个数。

    七.String

    String由双引号和字符串来表示,其实质是List。如"hello"等价于[$h,$e,$l,$l,$o].

    两个相邻的字符串将组合成一个字符串,即"he" "llo"等价于"hello"。

    也可以用Binary来表示字符串。

    八.Record

    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}

    九.Boolean

    没有该类型,但是可以用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

  • 相关阅读:
    CSS3属性transform详解之(旋转:rotate,缩放:scale,倾斜:skew,移动:translate)
    MySQL<添加、更新与删除数据>
    MySQL<数据库和表的基本操作>
    MySQL<数据库入门>
    MySql阶段案例
    Mysql综合案例
    Mysql课后思考题
    Java课后思考题
    Java课后简答题
    超全面的JavaWeb笔记day23<AJAX>
  • 原文地址:https://www.cnblogs.com/studynote/p/3218958.html
Copyright © 2011-2022 走看看