как подтипить записи с одобрения компилятора Эрланга? - PullRequest
1 голос
/ 15 февраля 2011

Я пытаюсь определить запись #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 ]

7 голосов
/ 15 февраля 2011

Не думаю, что это может сработать, потому что «-записать (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 голос
/ 15 февраля 2011

Если вы хотите наследовать в Erlang, используйте наследование модуля:

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

Также полезная функция «ООП» в Erlang - это параметризованные модули:

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

и используйте его:

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

Может быть, комбинация этих функций поможет вам.

...