Elisir - Funzioni

Una funzione è un insieme di istruzioni organizzate insieme per eseguire un'attività specifica. Le funzioni nella programmazione funzionano principalmente come le funzioni in matematica. Date alle funzioni un input, esse generano output in base all'input fornito.

Ci sono 2 tipi di funzioni in Elixir:

Funzione anonima

Funzioni definite utilizzando fn..end constructsono funzioni anonime. Queste funzioni sono talvolta chiamate anche lambda. Vengono utilizzati assegnandoli a nomi di variabili.

Funzione denominata

Funzioni definite utilizzando def keywordsono denominate funzioni. Queste sono funzioni native fornite in Elixir.

Funzioni anonime

Proprio come suggerisce il nome, una funzione anonima non ha nome. Questi vengono spesso passati ad altre funzioni. Per definire una funzione anonima in Elixir, abbiamo bisogno del filefn e endparole chiave. All'interno di questi, possiamo definire un numero qualsiasi di parametri e corpi di funzione separati da->. Per esempio,

sum = fn (a, b) -> a + b end
IO.puts(sum.(1, 5))

Quando si esegue il programma sopra, viene eseguito, genera il seguente risultato:

6

Notare che queste funzioni non vengono chiamate come le funzioni denominate. Noi abbiamo un '.'tra il nome della funzione e i suoi argomenti.

Utilizzo dell'operatore di cattura

Possiamo anche definire queste funzioni usando l'operatore di cattura. Questo è un metodo più semplice per creare funzioni. Definiremo ora la funzione di somma di cui sopra utilizzando l'operatore di cattura,

sum = &(&1 + &2) 
IO.puts(sum.(1, 2))

Quando il programma precedente viene eseguito, genera il seguente risultato:

3

Nella versione abbreviata, i nostri parametri non sono denominati ma sono disponibili come & 1, & 2, & 3 e così via.

Funzioni di corrispondenza dei modelli

Il pattern matching non è limitato solo alle variabili e alle strutture di dati. Possiamo usare il pattern matching per rendere le nostre funzioni polimorfiche. Ad esempio, dichiareremo una funzione che può prendere 1 o 2 input (all'interno di una tupla) e stamparli sulla console,

handle_result = fn
   {var1} -> IO.puts("#{var1} found in a tuple!")
   {var_2, var_3} -> IO.puts("#{var_2} and #{var_3} found!")
end
handle_result.({"Hey people"})
handle_result.({"Hello", "World"})

Quando il programma di cui sopra viene eseguito, produce il seguente risultato:

Hey people found in a tuple!
Hello and World found!

Funzioni denominate

Possiamo definire funzioni con nomi in modo da potervi facilmente riferire in seguito. Le funzioni denominate vengono definite all'interno di un modulo utilizzando la parola chiave def. Le funzioni denominate sono sempre definite in un modulo. Per chiamare funzioni denominate, dobbiamo fare riferimento ad esse utilizzando il nome del loro modulo.

Quanto segue è la sintassi per le funzioni denominate:

def function_name(argument_1, argument_2) do
   #code to be executed when function is called
end

Definiamo ora la nostra funzione con nome sum all'interno del modulo Math.

defmodule Math do
   def sum(a, b) do
      a + b
   end
end

IO.puts(Math.sum(5, 6))

Quando si esegue il programma sopra, produce il seguente risultato:

11

Per le funzioni a 1 riga, c'è una notazione abbreviata per definire queste funzioni, usando do:. Ad esempio:

defmodule Math do
   def sum(a, b), do: a + b
end
IO.puts(Math.sum(5, 6))

Quando si esegue il programma sopra, produce il seguente risultato:

11

Funzioni private

Elixir ci fornisce la possibilità di definire funzioni private a cui è possibile accedere dall'interno del modulo in cui sono definite. Per definire una funzione privata, utilizzaredefp invece di def. Per esempio,

defmodule Greeter do
   def hello(name), do: phrase <> name
   defp phrase, do: "Hello "
end

Greeter.hello("world")

Quando il programma di cui sopra viene eseguito, produce il seguente risultato:

Hello world

Ma se proviamo solo a chiamare esplicitamente la funzione della frase, usando il Greeter.phrase() funzione, solleverà un errore.

Argomenti predefiniti

Se vogliamo un valore predefinito per un argomento, usiamo il argument \\ value sintassi -

defmodule Greeter do
   def hello(name, country \\ "en") do
      phrase(country) <> name
   end

   defp phrase("en"), do: "Hello, "
   defp phrase("es"), do: "Hola, "
end

Greeter.hello("Ayush", "en")
Greeter.hello("Ayush")
Greeter.hello("Ayush", "es")

Quando il programma di cui sopra viene eseguito, produce il seguente risultato:

Hello, Ayush
Hello, Ayush
Hola, Ayush