如何在 erlang 编译器批准的情况下对记录进行子类型化?

发布于 2024-10-17 06:03:54 字数 1187 浏览 7 评论 0原文

我试图定义一个记录 #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]).

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

I am trying to define a record #a and a record #b such that #b extends #a, so that I can treat #b (and other subtypes of #a) as #a in some situations. The compiler, though, does not like it and keeps trying to guess the record type based on the first access I make to it. The following code triggers the warning.

-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]).

Is there anyway I can use this subtyping and make the compilation warning go away?
Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

说不完的你爱 2024-10-24 06:03:54

我认为这行不通,因为“-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 ,请...

I don't think this can work, because "-record(a,{alfa,beta})." is sort of a template for "{a, alfa, beta}" and "-record(b,{alfa,beta,gama})." results in a tuple "{b,alfa,beta,gama}".

Have a look at http://erlang.org/doc/getting_started/record_macros.html#id66845 , please...

一紙繁鸢 2024-10-24 06:03:54

如果你想在 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

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

If you want inheritance in Erlang use module inheritance:

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

Also useful "OOP" feature in Erlang is parameterized modules:

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

and use it:

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

Maybe combination of these features helps you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文