当前位置: 代码迷 >> 综合 >> erlang中的类型表示(-spec,-type)
  详细解决方案

erlang中的类型表示(-spec,-type)

热度:54   发布时间:2023-11-23 01:48:04.0

文章目录

      • 前言
      • -spec 类型规范
      • -type 类型定义
      • 类型的注解
      • 比类型注解更好的办法

前言

看《erlang程序设计》,第一次接触第九章类型几乎什么都没看懂,简单就掠过去了,后来回锅炒以及看了一些内置模块的源码,来有所悟。下面就是我对类型表示的一些理解。


补充强调:-spec和-type类型表示法,仅仅是一种说明性语法,对实际参数或返回值类型并不做限制,也就是说,它告诉:你这里参数只有这样填入我才能保证你会有这样的输出,否则如果你不按要求来,我虽然接受,但后果自负!!!。

直接上代码(《erlang程序设计》原书代码片段):

-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(_A,_B)->% 代码省略。...

-spec 类型规范

-spec 表示这是对一个函数进行规范,人话就是:说明函数的参数或者返回值的类型。因为erlang的函数定义没有参数类型和返回值类型说明,所以利用-spec 来单独定义。
并且-spec plan_route(point(),point()) -> route(). 这一行仅仅是对函数的规范,没有函数体,所以你还要在再编写一个具体实现的函数。

-type 类型定义

定义-spec具体可以使用的类型。通过上面的代码应该能发现,-spec规范总使用的全是利用-type定义的类型。它有具体的格式:

T1 :: A | B | C ...  

也就是T1 代表等下回引用的名称,它可以是A,B,C等中的一个。
并且A,B,C可以是其他-type定义的类型,就像上面代码一样。
除此之外还有一些erlang早就定义好的基本类型,我就将表放在了最后。

类型的注解

-spec plan_route(point(),point()) -> route().
这行代码虽然规范了plan_route函数的参数,返回值类型,但是你能却根本没有一点具体含义的提示,你知道这个函数是干嘛的吗?
当然不知道。
所以有了对类型的注解。
写法: -spec plan_route( Name1 :: point(), Name2 :: point()) -> route().
利用Name1,和Name2来提示类型的信息。

比类型注解更好的办法

对于-spec的写法,完全体其实是这样的:

-spec functionName(T1,T2,T3...Tn) -> Tret WhenTi :: Typei,Tj :: Typej,...

意思就是,现在我们将所有类型的注解全部写在 when关键后面,并取一个靓丽的名称,然后参数和返回值类型只要引用这个靓丽的名字就可以了。
改进一下之前的代码如下:

-module(walks).
-export([plan_route/2]).%% 注意看这里 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
-spec plan_route(Name1,Name1) -> Name2 whenName1 :: point(),Name2 :: route().-type direction() :: north() | south() | east() | west.
-type point() :: {
    integer() , integer()}.
-type route() :: [{
    go,direction(),integer()}].plan_route(_A,_B)->% 代码省略。...

erlang的预定义类型:

类型
-type term() :: any()
-type boolean() :: true | false
-type byte() :: 0 … 255
-type char() :: 0 …16#10ffff
-type number() :: integer() | float()
-type list() :: [any()]
-type maybe_improper_list() :: maybe_improper_list(any(),any())
-type maybe_improper_list(T) :: maybe_improper_list(T,any())
-type string() :: [char()]
-type nonempty_string() :: [char(),…]
-type iolist() :: maybe_improper_list(byte() | binary() |iolist() | binary() | [])
-type module() :: atom()
-type mfa() :: {atom() ,atom(), atom()}
-type node() :: atom()
-type timeout() :: infinity | non_neg_integer()
-type no_return() :: none()
  相关解决方案