2010-12-01 6 views
12

J'ai 2 parties de code que je veux exécuter. Les deux sont conditionnelsErlang équivalent à sinon

if Value1 < N do something 

else if Value1 >= N do something 

if Value2 < N do something 

else if Value2 >= N do something 

Je veux que chaque instruction s'exécute.

Comment fonctionne le si travailler dans erlang? il n'y a pas d'autre. J'utilise plusieurs gardes, mais il semble que j'ai 4 déclarations. par groupes de 2.

if some condition 
code; 

if other condition 
code 

end. 

Je reçois une erreur de syntaxe.

+0

J'ai trouvé que si vous vous reposez sur des gardes ou des déclarations de cas, vous êtes probablement "mal fait" la plupart du temps dans Erlang. Vous devriez probablement faire une correspondance de modèle la plupart du temps à Erlang comme alternative aux gardes et aux déclarations de cas. Sans un exemple concret, nous ne pouvons pas vous dire si vous devriez faire un cas, un garde ou une correspondance de modèle, mais la correspondance de modèle est __always__ écrire par rapport aux alternatives. –

+0

duplication possible de [Comment implémenter if-else] (http://stackoverflow.com/questions/963918/how-to-implement-if-else) –

Répondre

18

La forme d'un if est:

if 
    <guard 1> -> <body1> ; 
    <guard 2> -> <body2> ; 
    ... 
end 

Cela fonctionne essayer les gardes dans les clauses if dans l'ordre descendant (ceci est défini) jusqu'à ce qu'il atteigne un test qui réussit, alors le corps de cette clause est évalué et l'expression if renvoie la valeur de la dernière expression dans le corps. Donc, le bit else dans d'autres langues est cuit dedans. Si aucun des gardes n'aboutit, une erreur if_clause est générée. Un garde attrape-tout commun est juste true qui réussit toujours, mais un fourre-tout peut être tout ce qui est vrai.

La forme de case est:

case <expr> of 
    <pat 1> -> <body1> ; 
    <pat 2> -> <body2> ; 
    ... 
end 

Il fonctionne en évaluant d'abord, puis essayer de faire correspondre cette valeur avec des motifs dans le cas-clauses pour op-down (ce qui est défini) jusqu'à ce qu'un matchs , puis le corps de cette clause est évalué et l'expression case renvoie la valeur dernière expression dans le corps. Si aucun modèle ne correspond, une erreur case_clause est générée.

Notez que if et case sont les deux expressions (tout est une expression) afin qu'ils les deux doivent retourner des valeurs. C'est l'une des raisons pour lesquelles il n'y a pas de valeur par défaut si rien ne réussit/correspond. Aussi pour vous forcer à couvrir toutes les options; ceci est particulièrement important pour case. if est juste un cas dégénéré de case donc il a hérité. Il y a un peu d'histoire de if dans la logique d'Erlang que vous pouvez trouver sur trapexit.org sous les contributions de l'utilisateur.

13

Erlang ne vous permet pas d'avoir un if sans option d'instruction true. Il est à vous de décider si c'est quelque chose qui est une véritable déclaration ou un vrai true, mais il est courant que votre true soit le else dans d'autres langues.

if 
    some_condition -> some_code; 
    some_other_condition -> some_other_code; 
    true -> else_code 
end. 

Voir la "Qu'est-ce que le cas?" section sur this page pour plus à ce sujet.

+4

Cela permet certainement d'avoir un 'if' sans un' true 'branche, et va lancer une exception au moment de l'exécution dans ce cas. –

+1

Par conséquent, "erlang ne permet pas au jouet d'avoir une option" if "sans option" true ".". Si rien ne vaut 'true', vous obtiendrez une exception. –

+4

Mais obtenir une exception EST bon. Cela signifie qu'un cas ne s'est pas déroulé comme prévu. On pourrait argumenter qu'attraper toutes les clauses 'else' est aussi mauvais que d'attraper aveuglément toutes les exceptions: si X> 0 -> ...; X < 0 -> ...; X =: = 0 -> ... fin. Est plus explicite et sûr que d'utiliser 'true' pour la dernière clause. –

5

Tout d'abord, je vous recommande de vous habituer à utiliser la déclaration « cas », en raison de « si » les conditions restreintes pour garder les expressions:

case custom_call(A) of 
    1 -> do1(A); 
    2 -> do2(A) 
end. 

Il y a une autre façon de faire l'exécution conditionnelle en plus ' si » et 'espèce' qui fonctionne à partir de R13:

1> N =10. 
    10 
    2> ((N > 10) andalso more).  
    false 
    3> ((N == 10) andalso equals). 
    equals 
+0

Si j'utilise un étui, ne le sortira-t-il pas lorsqu'il correspond à un cas? Ou va-t-il exécuter ce cas et passer à essayer de correspondre à la seconde? – jarryd

+0

Il n'y a aucune raison d'utiliser aveuglément le cas ... de ... la fin au lieu de si. Si votre vérification peut être limitée aux gardes, utilisez «si». Sinon, vous compliquez inutilement votre code avec des clauses de correspondance vides dans un 'cas'. –

+0

Ok, mais ma question demeure. Le code quittera-t-il les instructions if s'il en exécute une? Ou va-t-il exécuter la déclaration et passer à la prochaine garde? J'ai besoin de code à exécuter en fonction de la valeur. et puis j'ai une autre méthode qui devrait faire la même chose en fonction d'une autre valeur. D'abord if est Value> = queue: len et l'autre devrait être Value jarryd

5

Rappelez-vous que if dans Erlang a une valeur à renvoyer, et c'est une expression.C'est pas que if comme en C ou Java.

Si vous voulez faire quelque chose pour une valeur, le code devrait être quelque chose comme ceci; Pour plus de détails, voir Section for the if expression of Erlang Reference Manual.