2016-04-04 30 views
2

看着二郎文档,有时我遇到类型规格,该文档的功能型没有真正指定类型...如何将一个类型记录为一个名称?

很难解释,所以让我给你一个example。在gen_serverhandle_call功能显示为在文档中的情况如下:

Request = term() 
From = {pid(),Tag} 
State = term() 
Result = {reply,Reply,NewState} | {reply,Reply,NewState,Timeout} 
    | {reply,Reply,NewState,hibernate} 
    | {noreply,NewState} | {noreply,NewState,Timeout} 
    | {noreply,NewState,hibernate} 
    | {stop,Reason,Reply,NewState} | {stop,Reason,NewState} 
Reply = term() 
NewState = term() 
Timeout = int()>=0 | infinity 
Reason = term() 

这里类型Tag从未显示(即,它只是一个变量名称)。

edoc是否可以做同样的事情?我发现最接近的是不透明的类型规格,但是它将它记录为抽象 - 是这样吗?

回答

2

只要函数中的变量名称(在所有子句中)和在@spec中使用的名称相同,这是可能的。例如。

%% @spec start_link(Args) -> {ok, pid()} 
start_link(Args) -> 
    gen_server:start_link(?MODULE, Args, []). 

会生成以下文档

start_link(Args) -> {ok, pid()} 

如果你有例如

%% @spec start_link(Args) -> {ok, pid()} 
start_link(Num) when is_integer(Num) -> 
    gen_server:start_link(?MODULE, [], []); 
start_link(Args) -> 
    gen_server:start_link(?MODULE, Args, []). 

不同的名称这将产生如

start_link(Num::Args) -> {ok, pid()} 

假设参数数量的类型。

我个人不推荐使用edoc @spec,而是使用-spec,因为它们被dialyzer使用,因此可以验证。

edoc也可以从-spec生成文档。鉴于-spec和@spec,edoc将覆盖到@spec指令。

%% @spec start_link(Args) -> {ok, Pid} 
-spec start_link(term()) -> {ok, pid()}. 
start_link(Args) -> 
    gen_server:start_link(?MODULE, Args, []). 

上面会导致

start_link(Args) -> {ok, Pid} 

并从上面卸下@spec将导致

start_link(Args::term()) -> {ok, pid()} 
+0

同意,建议不要使用EDOC @spec,而使用-spec。 –

0

据我所知,这对Edoc来说是不可能的。

我试图用这样的规格:

-spec foo(Something) -> term(). 
foo(X) -> 
    X. 

虽然电子文档实际上是感到高兴,并给出了型号规格作为文档foo(Something)没有指定什么Something,编译器抱怨它,并说:

type variable 'Something' is only used once (is unbound) 

所以你必须写:

-spec foo(Something::_) -> term(). 
foo(X) -> 
    X. 

,其显示为foo(Something::term()),由此给出Something的类型说明。

使用一个仅EDOC型规格:

%% @spec foo(Something) -> term() 
foo(X) -> 
    X. 

EDOC对待Something作为适用于该可变X并提出foo(X::Something)文档中类型名称。

因此,这两种方法都无法达到您想要的效果。

相关问题