Erlang(七)类型

意义

  1. 定义各种自定义数据类型

  2. 定义函数的参数及返回值

  3. dialyzer 进行代码静态分析

  4. edoc利用这些信息生成文档

-module(walks).
-export([plan_route/2]).
-spec plan_route(point(), point()) -> route().
-type direction() :: north | south | east | west.
-type point()     :: {integer(), integer()}.
-type route()     :: [{go,direction(),integer()}].

类型声明

plan_route({X1,Y1}, {X2, Y2}) ->
    [].
-type angle()       :: {Degrees::0..360, Minutes::0..60, Seconds::0..60}.
-type position()    :: {latitude | longitude, angle()}.
-spec plan_route1(From::position(), To::position()) -> [].

加上注解

语法

T1 :: A | B | C

定义新类型语法

-type newTypeName(Tvar1, Tvar2, ...) :: Type.

Tvar可选变量,Type为类型表达式

预定义类型

Built-in typeStands forterm()
any()
bool()
'false' | 'true'
byte()
0..255
char()
0..16#10ffff
non_neg_integer()
0..
pos_integer()
1..
neg_integer()
..-1
number()
integer() | float()
list()
[any()]
maybe_improper_list()
maybe_improper_list(any(),
any())
maybe_improper_list(T)
maybe_improper_list(T,
any())
string()
[char()]
nonempty_string()
[char(),...]
iolist()
maybe_improper_list(
char()|binary()|iolist(),
binary()|[])
module()
atom()
mfa()
{atom(),atom(),byte()}
node()
atom()
timeout()
'infinity'|non_neg_integer()
no_return()
none()

指定函数的输入输出类型

-spec funcitonName(T1, T2, T3...Tn) -> Tret when
    Ti :: Typei,
    Tj :: Typej,
    ...

导出类型和本地类型

(让其他模块可以使用导出的类型)

-module (a).
-type rich_text() :: [{font(), char()}].
-type font() :: integer().
-export_type([rich_text/0,font/0]).
-module(b).
..
-spec rich_text_length(a:rich_text()) -> integer().

dialyzer

dialyzer
  Checking whether the PLT /root/.dialyzer_plt is up-to-date...
dialyzer: Could not find the PLT: /root/.dialyzer_plt
Use the options:
   --build_plt   to build a new PLT; or
   --add_to_plt  to add to an existing PLT

For example, use a command like the following:
   dialyzer --build_plt --apps erts kernel stdlib mnesia
Note that building a PLT such as the above may take 20 mins or so

If you later need information about other applications, say crypto,
you can extend the PLT by the command:
  dialyzer --add_to_plt --apps crypto
For applications that are not in Erlang/OTP use an absolute file name.

dialyzer –build_plt –apps erts kernel stdlib

dialyzer --build_plt --apps erts kernel stdlib 
  Compiling some key modules to native code... done in 1m42.16s
  Creating PLT /root/.dialyzer_plt ...
Unknown functions:
  compile:file/2
  compile:forms/2
  compile:noenv_forms/2
  compile:output_generated/1
  crypto:des3_cbc_decrypt/5
  crypto:start/0
Unknown types:
  compile:option/0
 done in 2m11.26s
done (passed successfully)

plt持续性查询表

错误使用内置函数的返回值

内置函数的参数错误

错误的程序逻辑

typer可以打印出错误类型的推测类型

开始编写一个新模块时,应该先考虑类型并声明它们

类型推断是指通过分析代码得出函数类型的过程,分析程序,寻找约束条件,用约束条件构建一组约束方程,然后求解。

没有找到类型错误,并不意味着代码是正确的,仅仅是指程序里所有数据类型的使用方式相互一致。

erlang9