有没有办法查找默认记录值? [英] Is there a way to do lookups on default record values?

查看:165
本文介绍了有没有办法查找默认记录值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定记录

-record(something, {id                :: integer(),
                    name              :: string(),
                    email = undefined :: string() | undefined}).

有没有办法获取字段的默认值,在这个例子中, code>#something.email 默认为undefined?

Is there a way to get the default values for the fields, in this example getting the fact that #something.email defaults to undefined?

推荐答案

Erlang中的语法糖,由编译器扩展。以下解决方案由@Dmitry建议,但是编译器不会优化它,除非你通过+内联,因为这里的诀窍是真正创建一个记录:

Records are syntactic sugar in Erlang, expanded by the compiler. The following solution, suggested by @Dmitry, works, but the compiler will not optimize it away unless you pass +inline, since the trick here is to really create a record:

g() -> (#something{})#something.email.

这样的记录语法糖将被扩展为:(使用 erlc -E

Such record syntactic sugar will be expanded to: (use erlc -E)

g() ->
    case {something,undefined,undefined,undefined} of
        {something,_,_,rec0} ->
            rec0;
        _ ->
            error({badrecord,something})
    end.

,这将最终变成:(使用 erlc -S

and this will eventually become: (use erlc -S)

{function, g, 0, 4}.
  {label,3}.
    {line,[{location,"test.erl",10}]}.
    {func_info,{atom,test},{atom,g},0}.
  {label,4}.
    {move,{literal,{something,undefined,undefined,undefined}},{x,0}}.
    {test,is_tuple,{f,5},[{x,0}]}.
    {test,test_arity,{f,5},[{x,0},4]}.
    {get_tuple_element,{x,0},0,{x,1}}.
    {get_tuple_element,{x,0},3,{x,2}}.
    {test,is_eq_exact,{f,5},[{x,1},{atom,something}]}.
    {move,{x,2},{x,0}}.
    return.
  {label,5}.
    if_end.

#something.email 表达式不仅意味着获取创建的记录的电子邮件字段,而且还检查传递的记录是否格式良好。此测试目前未被优化。幸运的是,您可以在模块中使用 -compile([inline])。来优化它,或者在命令中 + inline

The #something.email part of the expression not only means getting the email field of the created record, but also checking that the passed record is well formed. This test is currently not optimized by default. Fortunately, you can optimize it with -compile([inline]). in your module or +inline on the command line.

以下解决方案对于编译器来说更为简单:

The following solution is simpler for the compiler:

f() -> element(#something.email, #something{}).

记录句法糖(这里#something.email是电子邮件字段的索引)将扩展为: / p>

Record syntactic sugar (here #something.email is the index of email field) will expand to:

f() ->
    element(4, {something,undefined,undefined,undefined}).

在这种情况下,我们不会告诉Erlang测试关于 #something的任何内容{} 是一个适当的#something记录。编译器总是优化调用 element / 2 内置函数。所以这将最终成为:

In this case, we do not tell Erlang to test anything about #something{} being a proper #something record. The compiler always optimizes calls to element/2 built-in function. So this will eventually become:

{function, f, 0, 2}.
  {label,1}.
    {line,[{location,"test.erl",7}]}.
    {func_info,{atom,test},{atom,f},0}.
  {label,2}.
    {move,{atom,undefined},{x,0}}.
    return.

请注意,任何字段的默认值为 undefined 除非明确提供。因此,您的代码:

Please note that the default value for any field is undefined unless explicitly provided. As a result, your code:

-record(something, {id                :: integer(),
                    name              :: string(),
                    email = undefined :: string() | undefined}).

相当于:

-record(something, {id    = undefined :: integer() | undefined,
                    name  = undefined :: string()  | undefined,
                    email = undefined :: string()  | undefined}).

然而,你的代码似乎意味着id总是一个 integer() ,从不 undefined ,同样该名称始终为 string()。这是不真实的如果这是你的意思,你应该提供一个默认值,不同于 undefined

Yet, your code seems to mean that id always be an integer() and never undefined, and likewise that name always be a string(). This is untrue. If this is what you mean, you should provide a default value different from undefined:

-record(something, {id    = 0   :: integer(),
                    name  = ""  :: string(),
                    email       :: string()}).

只提供默认值会告诉 dialyzer ,ID和名称永远不能未定义

Only providing a default value will tell dialyzer that id and name can never be undefined.

这篇关于有没有办法查找默认记录值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆