Home Rhyylen
Contatto
 
 
 
Crystal Language
Capitolo 13
Tipo unione

Il tipo unione, come dice il nome stesso è composto dall'unione di tipi diversi. Abbiamo già incontrato questo particolare tipo ad esempio utilizzando la funzione gets() per leggere lo standard input in quanto esso restituisce un elemento che può effettivamente essere una stringa oppure nil ovvero un valore nullo. Il valore di una variabile o di una espressione, come scritto sulla documentazione ufficiale, può in effetti essere un tipo unione. Un esempio facile è il seguente:
 
  Esempio 13.1
1
2
3
4
5
6
7
8
9
print "Inserisci un numero: "
s1 = gets()
n1 = (s1.to_s).to_i
if n1 > 1
y = 1
else
y = "ciao"
end
puts typeof(y)

il cui output è :

(Int32 | String)

mentre la classe, ottenibile con y.class, sarà quella a cui effettivamente appartiene y (ecco un esempio in cui typeof e class divergono). L'output ottenuto significa che la nostra variabile y ha una natura duplice che può essere di intero o di stringa. Tale natura è creata e gestita dal compilatore direttamente. Il numero di tipi contenuti in una unione non ha teoricamente alcuna limitazione, ad esempio se modifichiamo l'esempio precedente come segue per quanto riguarda la parte di selezione:

if n1 == 1
y = 1
elsif n1 == 2
y = "ciao"
elsif n1 == 3
y = 'a'
else
y = 1.34
end

l'output dell'istruzione alla riga 9 dell'esempio precedente sarebbe:

(Char | Float64 | Int32 | String)

Interessante e utile notare che applicare un metodo ad una variabile di tipo unione rende necessario che tutti i tipi dell'unione rispondano al metodo, altrimenti si avrà un errore, questo anche nel caso in cui prevediamo che il risultato dell'elaborazione darà un tipo su cui io metodo sia applicabile. Ad esempio non è possibile applicare un metodo che lavora solo su intero e numeri con virgola ad un tipo unione costituito da un intero e da una stringa.
Applicando alle tuple o alle tuple con nome abbiamo un interessante mix:

  Esempio 13.2a   Esempio 13.2b
1
2
3
4
5
6
7
8
t01 = {"uno", "due"}
t02 = {1, 2}
if 1 > 2
t03 = t01
else
t03 = t02
end
puts typeof(t03)
1
2
3
4
5
6
7
8
t01 = {x: "uno", y: "due"}
t02 = {z: 1, t: 2}
if 1 > 2
t03 = t01
else
t03 = t02
end
puts typeof(t03)

Con questo output rispettivamente:

Tuple(Int32 | String, Int32 | String) (NamedTuple(x: String, y: String) | NamedTuple(z: Int32, t: Int32))

Ricordate che un tipo unione può anche contenere il valore nil per cui è può tornare utilissimo nel gestire errori. Troveremo il tipo Union in molto diffusamente in Crystal. Molto comodo per tante situazioni, il suo utilizzo non va però abusato perchè aumenta la complessità del codice e la sua pesantezza.