如何使用erlang的编译器批准子类型记录?

时间:2011-02-15 12:32:54

标签: erlang compiler-warnings record

我正在尝试定义记录#a和记录#b,使得#b扩展#a,这样我就可以在某些情况下将#b(以及#a的其他子类型)视为#a。但是编译器并不喜欢它,并且一直试图根据我对它的第一次访问来猜测记录类型。以下代码触发警告。

-module(sandbox).  
-record(a,{alfa,beta}).  
-record(b,{alfa,beta,gama}).  
-export([test/0]).
test() ->  
    A = #b{alfa=1,beta = 2,gama=3},  
    self()!{msg,A},  
    receive  
    {msg,Msg} ->  
        Alfa = Msg#b.alfa,
        Beta = Msg#b.beta,
        case is_record(Msg,b) of
            true ->
                Gama = Msg#b.gama;
            false->                  %% Warning. Erlang assumes that Msg is a #b and therefore this will never match.
                Gama = []
        end
end,
io:format("~p ~p ~p",[Alfa,Beta,Gama]).


test1() ->
A = #b{alfa=1,beta = 2,gama=3},
self()!{msg,A},
receive
    {msg,Msg} ->
        Alfa = Msg#a.alfa,
        Beta = Msg#a.beta,
        case is_record(Msg,b) of
            true ->                  %% Warning. Erlang assumes that Msg is an #a, and therefore this will never match.
                Gama = Msg#b.gama;
            false->
                Gama = []
        end
end,
io:format("~p ~p ~p",[Alfa,Beta,Gama]).

无论如何我可以使用这个子类型并使编译警告消失吗? 感谢。

2 个答案:

答案 0 :(得分:7)

我不认为这可行,因为“-record(a,{alfa,beta})。”是“{a,alfa,beta}”和“-record(b,{alfa,beta,gama})的模板。”结果是一个元组“{b,alfa,beta,gama}”。

请查看http://erlang.org/doc/getting_started/record_macros.html#id66845,请...

答案 1 :(得分:1)

如果你想在Erlang中继承,请使用模块继承:

-module(inh).
-extends(base).

Erlang中另外有用的“OOP”功能是参数化模块:

-module(param, [Id, Name]).
-compile(export_all).
id() -> Id.
name() -> Name.

并使用它:

P = param:new(1, stas).
P:id(). % returns 1
P:name(). % returns stas

也许这些功能的组合可以帮助您。