|
Come in tutti gli altri linguaggi anche in V sono presenti le variabili, ovvero identificatori che si riferiscono ad una zona di memoria in cui cui sono conservati dei valori. Iniziamo quindi a parlare degli identificatori. Da un punto di vista formale relativamente alla loro composizione valgono le seguenti regole:
Sulla lunghezza non ho trovato vincoli per cui penso ci sia molto spazio. Come dico sempre, fate le vostre prove. Ricordate che il linguaggio V è case sensitive quindi l'identificatore "ciao" è diverso da "Ciao" o da "ciAo".Un caso particolare è costituito dalla variabile costituita da un solo carattere underscore _ che rappresenta una variabile che è possibile ignorare, utile come vederemo in casi particolari ed espressiva in tali situazioni. Detto questo vediamo come si dichiarano le variabili: 1° modo - sfruttando l'inferenza di tipo, ovvero il meccanismo che desume il tipo di una variabile attraverso il valore iniziale che viene attribuito nella parte destra della dichiarazione x1 := 8 noterete che in questo linguaggio, come in Pascal, l'operatore che effettua il binding è := invece del solito = tipico di tanti linguaggi come C/C++, Java, C, Rust ecc.. l'operatore di uguaglianza = viene invece usato per riassegnare un valore, ovvero attribuire un nuovo valore ad una variabile che già ne ha uno. E' possibile effettuare dichiarazioni in parallelo: x1, x2, x3 := 1, 2, 3 2° modo - esplicitando il tipo manualmente il tipo attraverso (tipo)valore, ad esempio x1 := i64(4) x2 := i8(7) che forza x1 ed x2 rispettivamente ad appartenere agli interi 64 e 8 bit invece degli interi 32 bit che è il default. 3° modo - creando variabili modificabili. Le variabili create nei due modi precedenti infatti sono non modificabili, ad esempio come quelle introdotte dalla sola istruzione let in Rust. In V la dichiarazione è molto semplice e fa uso, come in Rust, della leyword mut: mut x1 := 0 x1 = 8 Questo è ovviamente un aspetto molto importante e va tenuto presente. Ripetiamo: - le variabili che abbiamo creato nel modo 1 e 2 non sono modificabili. Il compilatore vi restituirà un errore se provate a modificare il valore che avete inserito in sede di creazione - per generare variabili modificabili bisogna usare la keyword mut. ovviamente potete inizializzare variabili mutabili in parallelo così come abbiamo visto per quelle immutabili mut x1, mut x2 := 1, int32(2) Come avrete visto, tutte le variabili hanno un valore assegnato. Questo è obbligatorio, quando definite una variabile in V dovete attribuirgli un valore, diversamente da molti altri linguaggi. In questo modo si evita con certezza il rischio di cercare di usare variabili non inizializzate. Il compilatore inoltre emetterà sempre un warning se definire variabili e poi non le utilizzate. Se necessario è possibile inizializzare una variabile con espressioni più complesse: x1 := (7 + 8) * 5 o, come vedremo, tramite funzioni. Ci sono alcune peculiarità relative alla evariabili in V che vanno sottolineate. 1) non sono permesse variabili globali (almeno di deafult). 2) non è permessa la ridichiarazione o la redifinizione delle variabili 3) non è permesso lo shadowing e sono 3 aspetti interessanti. Il primo è una scelta di design che ha i suoi pro e i suoi contro. Senza scendere troppo in dettaglio, in genere facilita la scrittura del codice, potendoci appoggiare su una variabile accessibile ovunque, dall'altro è un approccio più rischioso in termini di manuenzione del codice e rischio di race condition in sistemi complessi. Come avrete notato come, tra parentesi, sia specificato che questo è il compotamento di default. Il compilatore vi permettere di abilitare le variabili globali attraverso un flag che vedremo oltre. Il secondo punto mi piace molto. In pratica in altri linguaggi, è possibile ridefinire variabili già dichiarate. Ad esempio in Rust potete scrivere: let x1 = 9; let x1 = 'a'; vi sono scelte di design profonde dietro a questo, non è che un approccio sia meglio dell'altro. A me però questa cosa non piace, ne ho anche discusso sul forum di Rust. In pratica invece in V scrivere: x1 := 7 x1 := 9 origina un errore: error: redefinition of `x1` insomma, non potete farlo. Ripeto questo mi piace di più rispetto all'altro approccio, anche se, come detto vi sono ragioni valide anche dall'altra parte. Il terzo punto è interessante. In pratica in molti linguaggi possiamo scrivere cose come { x1 = 0; { x1 = 1; } } Ecco, V non si può fare, un ambito (praticamente il perimetro entro il quale una variabile è definita e che viene delimitato dalla coppia di parentesi graffe,) annidato all'interno di un altro non permette comunque dichiarare nuovamente una variabile. Ovvero il seguente codice è illegale in V: fn main() { x1 := 8 { x1 := 7 } } risultandone lo stesso errore precedente In altre parole una variabile dichiarabile in una data funzione, sia essa la pricnipale sia, come vedremo in un'altra, è unica. Anche in V esiste il concetto di valore costante che viene definito tramite un keyword ovvero const. Una variabile definita tramite essa non è più in alcun modo modificabile. Le costanti in questo linguaggio vanno dichiarate a livello di modulo, ovvero all'esterno di qualsiasi funzione. Per esempio il seguente codice non complica fn main { const x1 := 8 } mentre const x1 := 8 fn main { } va bene perchè la costante è esterna al metodo main. |