|
|
Crystal Language |
Capitolo 3 |
Type System |
Il type system di Crystal è stato pensato con il mente duttilità e
robistezza. Di seguito presentiamo le sue caratteristiche salienti,
qualcosa abbiamo già visto nel paragrafo precedente:
- Crystal è un linguaggio statically typed. Questo
significa che i tipi delle variabili sono determinati in fase di
compilazione, il che permette di rilevare errori di tipo prima di
eseguire il programma. Il linguaggio propone anche l'inferenza di tipo
automatica, quindi nella maggior parte dei casi non è
necessario specificare esplicitamente i tipi delle variabili o dei
parametri.
- Una caratteristiche potenti ed interessante del sistema di
tipi di Crystal è il supporto per i union types,
che consentono a una variabile di avere più di un tipo. Se una
variabile può assumere diversi tipi, Crystal la rappresenta come una
unione di quei tipi.
-
Segue un approccio orientato agli oggetti. Le classi in
Crystal sono simili a quelle di altri linguaggi orientati agli
oggetti, come Ruby, ma Abbiamo a disposizione anche strutture
(struct),
che sono tipicamente più leggere e non supportano l'ereditarietà.
-
Classi: Sono oggetti heap-allocated, il che
significa che sono allocati dinamicamente in memoria. Le classi
possono essere ereditate e sovrascritte.
-
Strutture (struct): Sono stack-allocated,
quindi più efficienti. Le
struct non supportano
l'ereditarietà, e le modifiche sono copiate per valore invece
che per riferimento.
- Crystal supporta l'ereditarietà e il polimorfismo. Una classe
può ereditare da un'altra e sovrascrivere i metodi della classe
genitore. Crystal utilizza il polimorfismo e le classi astratte per
definire comportamenti comuni che possono essere personalizzati
nelle classi derivate. L'ereditarieà è semplice, quindi non abbiamo
la potenza ma soprattutto i grattacapi dell'ereditarietà multipla.
- E' supportata la programmazione generica, permettendo di
definire classi, moduli e metodi che possono lavorare con diversi
tipi. I generici aiutano a scrivere codice riutilizzabile e
tipicamente più sicuro.
- Crystal mira a garantire la sicurezza dei tipi, riducendo al
minimo gli errori comuni come il null pointer exception. Questo è
ottenuto tramite l'uso esplicito di Nil nei tipi e l'inferenza del
tipo basata su flussi di controllo.
Questo è già tanto ma, come vedremo non è tutto.
Come al solito ci vuole uno schema da seguire, a mio avviso, per capire
bene cosa abbiamo a disposizione in questo linguaggio. Seppure non in
ordine i tipi chiave a mio avviso sono i seguenti:
Tipi
numerici |
- Int32: intero a 32
bit con segno.
- Int64: intero a 64
bit con segno.
- Int8, Int16:
interi a 8 e 16 bit con segno.
- UInt8,
UInt16,
UInt32, UInt64: interi
senza segno a 8, 16, 32, e 64 bit.
- Float 32 numeri
invirgola mobile 32 bit
- Float 64 numeri in
virgola mobile 64 bit
- BigInt numeri
arbitrariamente grandi
|
Booleani |
Bool che può assumere solo i valori true e
false |
Caratteri e stringhe |
- Char - singolo
carattere Unicode
- String - sequenza
mutabile di caratteri
|
Nil |
Nil: rappresenta l'assenza di valore. In
Crystal, le variabili possono assumere il valore nil solo se
esplicitamente previsto, come parte di un Union Type. |
Array |
Array(T) è la consueta collezione ordinata di
elementi dello stesso tipo T |
Hash |
Hash(K, V): una mappa mutabile di coppie
chiave-valore. Le chiavi devono essere uniche e dello stesso
tipo K, e i valori devono essere dello stesso tipo V. |
Tuple |
Tuple: una collezione immutabile di elementi di
tipi diversi. Le tuple possono contenere elementi di diversi
tipi e il loro numero di elementi è fissato. |
Named
Tuple |
NamedTuple: simile alla Tuple, ma gli elementi
sono accessibili tramite nomi associati. |
Range |
Range(T): rappresenta un intervallo di valori,
definito da un inizio e una fine, inclusivo o esclusivo. |
Symbol |
Symbol: simile a una stringa, ma è immutabile e
internamente rappresentato come un ID unico. |
Enum |
Enum: tipo definito dall'utente che rappresenta
un insieme limitato di valori. |
Struct |
Struct: simile a una classe, ma con alcune
differenze significative. Le struct sono allocate nello stack e
copiate per valore, il che le rende più efficienti in alcune
situazioni rispetto alle classi. |
Proc |
Proc(T): rappresenta un blocco di codice che
può essere salvato in una variabile e chiamato in un secondo
momento. Può avere argomenti e un tipo di ritorno. |
Fiber |
Fiber: rappresenta una piccola unità di
esecuzione concorrente che può essere messa in pausa e ripresa.
È il meccanismo principale di Crystal per la concorrenza senza
thread pesanti. |
Channel |
Channel(T): utilizzato per la comunicazione tra
Fiber. È un costrutto che permette di passare messaggi tra fiber
in modo sicuro. |
Time |
Time: rappresenta un istante temporale. |
Exception |
Exception: rappresenta un errore o un'eccezione
che può essere sollevata (raise) durante l'esecuzione del
programma. |
File |
File: rappresenta un file su disco e permette
la lettura e scrittura. |
IO |
IO: è la classe base per input/output in
Crystal. File, socket e altri stream derivano da questa classe. |
Ecco quello che ci aspetta nei prossimi
paragrafi... più o meno.
|