Erlang(10):類型分析和檢測

在Erlang中咱們能夠經過type及spec定義數據類型及函數原型。
經過這些信息,咱們對函數及調用進行靜態檢測,從而發現一些代碼中問題。
同時,這些信息也便於他人瞭解函數接口,也能夠用來生成文檔。
Type :: any()           %% 最頂層類型,表示任意的Erlang term
     | none()           %% 最底層類型,不包含任何term
     | pid() | port() | ref() | [] | Atom | Binary | float()
     | Fun | Integer | List | Tuple | Union | UserDefined 
Union :: Type1 | Type2
Atom :: atom()
     | Erlang_Atom      %% 'foo', 'bar', ...
Binary :: binary()                        %% <<_:_ * 8>>
       | <<>>
       | <<_:Erlang_Integer>>            %% Base size
       | <<_:_*Erlang_Integer>>          %% Unit size
       | <<_:Erlang_Integer, _:_*Erlang_Integer>>
Fun :: fun()                             %% 任意函數
    | fun((...) -> Type)                 %% 任意arity, 只定義返回類型
    | fun(() -> Type)
    | fun((TList) -> Type)
Integer :: integer()
        | Erlang_Integer                 %% ..., -1, 0, 1, ... 42 ...
        | Erlang_Integer..Erlang_Integer %% 定義一個整數區間
List :: list(Type)                       %% 格式規範的list (以[]結尾)
     | improper_list(Type1, Type2)       %% Type1=contents, Type2=termination
     | maybe_improper_list(Type1, Type2) %% Type1 and Type2 as above
Tuple :: tuple()                          %% 表示包含任意元素的tuple
      | {}
      | {TList}
TList :: Type
      | Type, TList
因爲 lists 常用,咱們能夠將 list(T) 簡寫爲 [T] ,而 [T, ...] 表示一個非空的元素類型爲T的規範列表。二者的區別是 [T] 可能爲空,而 [T, ...] 至少包含一個元素。
'_' 能夠用來表示任意類型。
list()表示任意類型的list,其等同於 [_]或[any()], 而 [] ,僅僅 表示一個單獨的類型即空列表。
爲了方便,下面是一個內建類型列表
term() 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()

定義新的類型:
-type NewTypeName(TVar1, TVar2, ... TVarN) :: Type.

函數規範的編寫方式
-spec functionName(T1, T2, ..., Tn) -> Tret when
    Ti :: Typei,
Tj :: Typej,
...

導出類型:
-export_type(typeName/0, typeName2/0).


不透明類型:
-opaque XXX : YYY.
隱藏XXX的內部細節。理論上是不但願在模塊外部使用XXX的內部細節。


dialyzer 
檢測程序裏的類型錯誤。主要是針對類型錯誤。
$dialyzer test.erl
dialyzer很容易受到干擾。因此要遵循幾條簡單規則:
避免使用-compile(export_all)。
爲模塊導出函數的全部函數提供詳細的類型規範。
爲記錄定義裏的全部元素提供默認的參數。
把匿名變量做用函數的參數常常會致使結果類型不如預想的那麼精確。
node


總結:這是一個頗有意思的功能,比C++的強制類型更加寬鬆,比Lua的弱類型又多了一個選擇。算是一個亮點。函數

相關文章
相關標籤/搜索