2010-03-23 5 views
3

J'essaie d'utiliser un enregistrement dans une garde comme décrit ici [1]. Si j'utilise la forme courte qui y est décrit:Enregistre dans un garde

handle(Msg, State) when Msg==#msg{to=void, no=3} -> 

... Je ne suis jamais un match ... Mais si j'élargissons pleinement à:

handle(Msg, State) when Msg#msg.to==void, Msg#msg.no==3 -> 

... tout va bien. Comme il semble que je le fais avec la plupart des docs erlang, est-ce que je le lis mal?

Merci, --tim

[1] - http://www1.erlang.org/doc/reference_manual/records.html#id2278275

+3

juste une supposition, mais votre première La correspondance suppose qu'il n'y a pas d'autres champs dans l'enregistrement ou que tous les autres champs sont définis sur indéfini. Si l'enregistrement msg comporte d'autres champs qui provoqueraient son échec. –

+0

Merci Jeremy, ça doit être ça (il y a d'autres champs de valeur), je pensais qu'ils étaient sémantiquement équivalents. Merci encore ... – Tim

+0

Juste comme une note supplémentaire, vous pourriez avoir fait cela avec la correspondance de modèle dans la signature de la fonction à la place. La correspondance a échoué car elle a effectué un test d'égalité. Vous avez peut-être été victime de la similarité visuelle de == pour l'égalité et = pour la liaison dans une correspondance de motif. –

Répondre

11

Lorsque vous indiquez #msg{to=void, no=3} dans une garde, tous les champs que vous n'avez pas mentionnés seront définis par défaut (généralement undefined). Votre garde ne correspond donc pas car certains des champs non listés ne correspondent pas.

J'ai tendance à toujours utiliser un modèle plutôt qu'un garde si possible, donc je voudrais écrire la clause comme:

handle(Msg = #msg{to=void, no=3}, State) -> 
    ... 

Ce modèle nécessite MESS pour enregistrer msg (un tuple la taille d'un enregistrement msg avec le premier élément étant msg), l'élément to doit être void et l'élément no doit être 3. Les autres éléments de l'enregistrement msg peuvent être n'importe quoi.

+0

Merci à tous, comme tout le monde l'a supposé, je devrais plutôt utiliser un motif ... cette courbe d'apprentissage est raide mais agréable ... merci encore ... – Tim

4

Je vois que vous avez résolu le problème déjà. Juste une remarque: dans idiomatiques Erlang vous auriez écrit habituellement le match comme celui-ci:

handle(Msg = #msg{to = void, no = 3}, State) -> 

Bien sûr, il revient au goût, et parfois vous aurez envie d'utiliser des gardes à la place pour obtenir plus agréable alignement de ligne .

4

Vous pouvez utiliser le modèle suivant à la place, sa succincte

handle(#msg{to=void, no=3}=Msg, State) -> 
    do_stuff(Msg). 

Si vous n'avez pas besoin toute valeur record msg, mais seulement un champ à l'intérieur, alors vous pouvez faire correspondre et destructives comme celui-ci

handle(#msg{to=void, no=3, data=Data}, State) -> 
    do_stuff(Data). 
0

Les enregistrements correspondants peuvent être très compliqués lorsqu'ils sont volumineux. La façon dont je traite est en testant le premier élément du dossier, qui devrait être le nom de l'enregistrement:

poignée (autre) lorsque l'élément (1, Msg) == msg

Questions connexes