Ricerca…


usi di base delle clausole di guardia

In Elixir, è possibile creare più implementazioni di una funzione con lo stesso nome e specificare regole che verranno applicate ai parametri della funzione prima di chiamare la funzione per determinare quale implementazione eseguire.

Queste regole sono contrassegnate dalla parola chiave when , e vanno tra il def function_name(params) e il do nella definizione della funzione. Un esempio banale:

defmodule Math do

  def is_even(num) when num === 1 do
    false
  end
  def is_even(num) when num === 2 do
    true
  end

  def is_odd(num) when num === 1 do
    true
  end
  def is_odd(num) when num === 2 do
    false
  end

end

Supponiamo che Math.is_even(2) con questo esempio. Esistono due implementazioni di is_even , con diverse clausole di guardia. Il sistema li guarderà in ordine ed eseguirà la prima implementazione dove i parametri soddisfano la clausola di guardia. Il primo specifica che num === 1 che non è vero, quindi passa a quello successivo. Il secondo specifica che num === 2 , che è vero, quindi questa è l'implementazione che viene utilizzata e il valore restituito sarà true .

Cosa succede se Math.is_odd(1) ? Il sistema esamina la prima implementazione e vede che poiché num è 1 la clausola di guardia della prima implementazione è soddisfatta. Utilizzerà quindi tale implementazione e restituirà true , senza preoccuparsi di esaminare altre implementazioni.

Le guardie sono limitate nei tipi di operazioni che possono eseguire. La documentazione di Elixir elenca tutte le operazioni consentite ; in poche parole consentono confronti, matematica, operazioni binarie, controllo del tipo (ad es. is_atom ) e una manciata di piccole funzioni di convenienza (ad es. length ). È possibile definire clausole di protezione personalizzate, ma è necessario creare macro ed è preferibile una guida più avanzata.


Nota che le guardie non lanciano errori; vengono considerati normali fallimenti della clausola di guardia e il sistema passa alla fase successiva. Se si scopre che si sta ottenendo (FunctionClauseError) no function clause matching quando si chiama una funzione protetta con params che si prevede di lavorare, potrebbe essere che una clausola di guardia che si prevede funzioni genererà un errore che viene ingerito.

Per vederlo da solo, crea e poi chiama una funzione con una guardia che non ha senso, come questa che prova a dividere per zero:

defmodule BadMath do
  def divide(a) when a / 0 === :foo do
    :bar
  end
end

La chiamata a BadMath.divide("anything") fornirà l'errore un po 'inutile (FunctionClauseError) no function clause matching in BadMath.divide/1 - mentre se si fosse tentato di eseguire "anything" / 0 direttamente, si otterrebbe un risultato più utile errore: (ArithmeticError) bad argument in arithmetic expression errato (ArithmeticError) bad argument in arithmetic expression .



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow