美文网首页
Erlang基础(三):异常,BIF,比特语法,编译与运行

Erlang基础(三):异常,BIF,比特语法,编译与运行

作者: 文卿 | 来源:发表于2015-10-06 17:39 被阅读401次

开篇

恩,被赤裸裸的打脸了,刚说完每周2更,结果拖到现在都没有一更。。恩。。虽然中间本人完成了人生大事的一部分--订婚。
好了,废话不多说,今天来介绍下 异常,内置函数,二进制数据和所对应的比特语法,以及如何编译和运行程序等等。

异常

  • 简介
    关于异常,其实在传统的编程语言里面使用的比较多,诸如:Java,C#。恩,C和C++是个例外。在erlang中,异常捕获的语法也大同小异.
try ... of
  Pattern [when guard] -> expression;
  ...other pattern...
catch
  exception type : Pattern [when guard] -> express;
  ...other pattern...
after
  expression;
  ...other expression...
end.
  • 异常捕获
    其中,try ... of 中是需要捕获异常的表达式或者函数。函数或者表达式的值,会逐步与 of 下面的模式进行匹配,并给出匹配到的表达式的值。
    在catch中,捕获异常类型。erlang定义的异常类型只有三种:
  throw-> 调用者处理的可忽略的异常,
  exit-> 程序退出类型异常,
  erlang:error -> 程序崩溃类型异常
  • Final Handling
    after处的表达式不论异常是否捕获,均会处理。根据传统语言的编程经验来看,此处比较适合处理资源释放,如:数据库连接释放,文件释放等等。

  • demo
    光说不练假把势,写一个捕获所有可能产生异常的函数,以及写一个产生所有异常的函数进行测试:


    demo1

    可以先忽略test2函数,稍后会说到。generate_exception/1 函数会产生一个函数被调用时所有可能出现的结果,catcher/1 函数尝试对这些结果进行异常捕获或者正常处理。test/0 函数将这些结果合并到一个列表中。

  • 另外一种写法
    当然,捕获异常还有另外一种写法:

catch expression.

直接捕获表达式中的异常.如 demo 代码中的 test2/0 函数.

  • 编程规范
    捕获异常还是有几种best practise的。如:
  1. 经常会返回错误的程序
  case ... of 
      {ok, Val} -> do_something(Val);
      {error, Why} -> %% do something with error message Why
 end.
  2. 出错几率小的代码
  try ...
  catch
    throw:{thisError, Val} -> ...
    exit:{otherError, Val} ->...
  end.
 3. 捕获所有可能的异常
  try expression
  catch
    _:_ -> ... %% 切记,此处不能写成 _ -> 。如此则捕获不到任何异常.
  end.

BIF

BIF 即 Built in functions,也就是内置函数,或称之为系统函数更为合适些。erlang中的BIF看起来像是函数,其实不然,他是针对于erlang虚拟机的操作指令。如:

@spec time() -> 获取当前时间

@spec lists:reverse(List) -> List. 翻转列表

@spec term_to_binary(Term) -> binary().  将所有erlang的值转换为二进制数据.n

注: @spec 为erlang中的文档标记用法

比特语法

  • 简介
    比特语法主要用于处理二进制数据,经常用于对于单个比特位或者比特位串进行封包或者解包。

  • Examples

%%解析COFF数据
-define(DWORD, 32/unsigned-little-integer).
-define(LONG, 32/unsigned-little-integer).
-define(WORD, 16/unsigned-little-integer).
-define(BYTE, 8/unsigned-little-integer).
<<Characteristics : ?DWORD,
     TimeDateStamp : ?DWORD,
     MajorVersion : ?WORD,
     MinVersion : ?WORD,
     NumberOfNamedEntries : ?WORD,
     NumberOfIdEntries : ?WORD>>.

上述代码参照COFF的结构体进行二进制数据读取,可见,尤为简单。无需移位,截断等等。

编译运行

运行的方式大致有三种,shell中运行,单文件编译运行,工程编译运行。

  • 运行环境设置
    erlang虚拟机自动加载模块时,首先要指定模块文件所在的路径,两种方式,可以在启动时,通过 -pa, -pz指定添加。pa 为加载搜索路径的头,pz 为加载搜索路径的末尾。也可以在 目录下的.erlang文件中,通过2个BIF添加 @spec code:add_patha(Dir), @spec code:add_pathz(Dir)前者加入到搜索路径的头,后者加入到搜索路径的末尾。如:
io:format("Allen@erlang virtual machine~n").
code:add_pathz(".");

运行结果:


  • shell运行
    shell运行时,如果需要退出,最佳方案是使用 q(). 方式进行退出,而不是erlang:halt(). 如果使用 erlang:halt(). 会使得部分程序(数据写入等)产生错误修复,再下一次启动时.
    若shell不允许输入时,只能通过杀掉进程的方式停止运行。注意,如果erlang程序是以 -heart Cmd 的方式启动,启动时会带上监控进程,监控进程在进程死亡时会执行Cmd,若Cmd的指令为重启程序,那么首先要杀掉这个监控进程。

  • 单文件编译运行
    可以在shell中,使用 c(filename).进行编译,然后使用模块对应的函数。如:

-module (hello).
-export([hi/0]).
-auth(allen).
-date("2015.08.28").
-vsn("1.0.0").
hi () ->
    "Hello World".

执行方式:



也可以在命令行下编译并执行,如:

erlc hello.erl
erl -noshell -s hello hi -s init stop

结果:



当然,还有一种方式则是编写 escript 或者 编写sh脚本运行程序。(使用 -eval 命令)--> 限于篇幅,将在后续IM工程中使用时介绍。

  • makefile
    赞叹下,makefile不愧为工程神器。从cpp,到erlang,到ELisp,到...。真是太赞了。
    所以,erlang的makefile写法与cpp的也没啥区别。
    下面列出一个简要的模板:
.SUFFIXES: .erl .beam
.erl.beam:
    erlc -W $<
ERL = erl -boot start_clean
MODS=hello
all: compile
    ${ERL} -pa "." -s hello hi
compile: ${MODS:%=%.beam}
clean:
    rm -rf *.beam erl_crash.dump

执行结果如下:


makefile
  • rebar
    当然,编写makefile也有点麻烦,业界比较好用的工具有个rebar。rebar不单单可以进行工程的编译,还可以创建工程模块,以及发布等等。非常强大。
    此处不做赘述,请移步Github

相关文章

  • Erlang基础(三):异常,BIF,比特语法,编译与运行

    开篇 恩,被赤裸裸的打脸了,刚说完每周2更,结果拖到现在都没有一更。。恩。。虽然中间本人完成了人生大事的一部分--...

  • [Python] (Day-16) - 错误和异常

    语法错误 语法错误或者称之为解析错 语法错误在编译时编译失败 示例: 异常 运行期检测到的错误被称为异常 异常处理...

  • java异常处理

    什么是异常 程序非正常编译和运行 语法错误不是异常,语法错误是编译器检查出现的错误,虽然在编译时就检查的受查异常也...

  • Java基础之异常处理

    Java基础之异常处理 在Java程序中,异常分为编译异常以及运行时异常 编译异常:程序在编译期间就出现的异常,必...

  • 十七:Java基础入门-Java的错误类型

    程序的错误分为编译期语法错误、运行期异常错误和运行期逻辑错误。 编译期语法错误可以借助IDE(集成开发环境,常见有...

  • C++基础-(异常)

    C++基础 异常 程序的错误,一种是编译错误,即语法错误。另一种是运行时发生的错误 异常与类的关系 进化版 万能捕...

  • 《Python光速入门》(8):异常处理

    主题 异常处理 总结 语法错误(编译器解决)、语义错误(Debugger解决)、运行时错误(捕获异常) 抛出异常抛...

  • 异常处理

    异常定义:运行期间出现的错误,而不是编译时的语法错误。异常体系结构 Error类:特指应用程序在运行期间发生的严重...

  • (三十二)单步调试技术

    编译错误与运行错误 编译错误:编译器提示的错误,低级错误,语法有错,根本无法生成exe文件 运行错误:程序运行的结...

  • 了解一下JavaScript的预编译

    JS运行三部曲 js运行代码共分三步 语法分析 预编译 解释执行 JavaScript代码在运行时,首先会进行语法...

网友评论

      本文标题:Erlang基础(三):异常,BIF,比特语法,编译与运行

      本文链接:https://www.haomeiwen.com/subject/mwogcttx.html