2 votes

Existe-t-il un moyen d'effectuer des recherches sur les valeurs d'enregistrement par défaut ?

Compte tenu d'un enregistrement

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

Existe-t-il un moyen d'obtenir les valeurs par défaut des champs, c'est-à-dire, dans cet exemple, d'obtenir le fait que #something.email a pour valeur par défaut undefined ?

7voto

Paul Guyot Points 5607

Les enregistrements sont du sucre syntaxique dans Erlang , élargi par le compilateur. La solution suivante, suggérée par @Dmitry, fonctionne, mais le compilateur ne l'optimisera pas à moins que vous ne passiez +inline, puisque l'astuce ici est de réellement créer un enregistrement :

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

Le sucre syntaxique de ce disque sera étendu à : (utiliser erlc -E )

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

et cela deviendra finalement : (utiliser 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.

En #something.email de l'expression permet non seulement d'obtenir le champ "email" de l'enregistrement créé, mais aussi de vérifier que l'enregistrement transmis est bien formé. Ce test n'est actuellement pas optimisé par défaut. Heureusement, vous pouvez l'optimiser avec -compile([inline]). dans votre module ou +inline sur la ligne de commande.

La solution suivante est plus simple pour le compilateur :

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

Le sucre syntaxique d'enregistrement (ici #quelquechose.email est l'index du champ email) se développera en :

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

Dans ce cas, nous ne demandons pas à Erlang de tester quoi que ce soit à propos de #something{} un vrai disque de #something. Le compilateur optimise toujours les appels à element/2 fonction intégrée. Cela deviendra donc un jour :

{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.

Veuillez noter que la valeur par défaut de tout champ es undefined sauf disposition explicite . En conséquence, votre code :

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

est équivalent à :

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

Pourtant, votre code semble signifier que l'id est toujours un integer() et jamais undefined De même, ce nom est toujours un string() . C'est faux. Si c'est ce que vous voulez dire, vous devriez fournir une valeur par défaut différente de undefined :

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

Seule la fourniture d'une valeur par défaut indiquera à dialyseur que l'identifiant et le nom ne peuvent jamais être undefined .

4voto

Dmitry Belyaev Points 1918

Construire un enregistrement vide et examiner un champ : (#something{})#something.email .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X