Archivi categoria: GOLANG

Serie di articoli dedicata a Golang, il linguaggio sviluppato da Google

TUTORIAL GO – METODI E INTERFACCE

Go non consente di definire le classi ma consente di definire dei metodi disponibili per una struttura.

Nel blocco sopra ho definito una struttura Persona che contiene nome e cognome. Per definire un metodo si usa una sintassi simile alla definizione di una funzione. Si usa la parola chiave func, definita dalla struttura cui si applica, il nome del metodo, la lista dei parametri che riceve in ingresso e l’eventuale output. Nello specifico ho definito un metodo iniziali che stampa le iniziali della persona.

Nell’esempio di sopra il metodo definito sfrutta il passaggio per valore, ovvero il metodo opera su una copia della struttura persona senza modificare i valori dell’istanza di partenza. Per ovviare a questo Go mette a disposizione il passaggio per riferimento, che si ottiene specificando il puntatore alla struttura.

Con questo approccio invocando il metodo iniziali si avrà l’effetto desiderato. In assenza del puntatore non si avrebbe l’effetto atteso.

Go mette a disposizione anche il costrutto interfaccia, ovvero permette di definire una lista di metodi che le strutture devono implementare

In questo caso ho definito una interfaccia Familiare che prevede il metodo iniziali, pertanto posso invocare il metodo iniziali su una variabile che implementa l’interfaccia Familiare

TUTORIAL GO – FUNCTIONS

Per definire una funzione Go mette a disposizione la parola chiave func seguita dal nome della funzione, l’elenco dei tipi attesi e l’elenco dei tipi restituiti, questo perchè in Go le funzioni possono restituire più valori in modo sequenziale,

Nel caso sopra ho definito la funzione duplica che riceve in ingresso una stringa e restituisce la string concatenata con se stessa

E’ possibile definire più parametri in ingresso e se i parametri sono dello stesso tipo Go permette di dichiarare il tipo una volta sola

In questo caso la funzione concatena riceve 2 stringhe in ingresso e le concatena dando il valore in uscita. Essendo parametri dello stesso tipo è possibile dichiarare il tipo una volta sola.

Anche in uscita è possibile definire più parametri

In questo la funzione restituisce la lunghezza delle 2 stringhe ricevute in ingresso. E’ possibile anche ignorare una delle 2 variabili tramite la parola chiave _.

Go mette anche a disposizione un meccanismo per definire un numero infinito di parametri in ingresso tramite la parola chiave …

In questo caso ho definito una lista di valori in ingresso e per ognuno di essi restituisco la lunghezza della parola

Go permette di ritornare la funzione come tipo di ritorno di una funzione e di assegnarla ad una funzione e di poterlo assegnare ad una variabile

Nell’esempio ho definito una funzione conta3 che riceve una lista di valori variabili in ingresso e che per ognuno di essi elabora la lunghezza e la stampa. Successivamente assegno la funzione ad una variabile e la eseguo invocando la variabile stessa con i parametri in ingresso. Posso ottenere un comportamento analogo definendo la function direttamente dopo il nome della variabile ma in questo caso perdo la gestione della variabile di stato counter.

Infine Go supporta la ricorsione ovvero una funzione che elabora il risultato richiamando se stesso e basando il tutto su una condizione di uscita. Classico esempio è la funzione fattoriale

TUTORIAL GO – ARRAY, SLICES e MAP

Cosa è un array ? E’ una sequenze definita di valori dello stesso tipo e prevede fin dall’inizio di stabilire quanti elementi contenga.

la sintassi per definire l’array prevede la parola var, il nome della variabile (in questo caso ar), numero di elementi in esso contenuti previsti compreso tra [] e il tipo degli elementi. In assenza di inizializzazione si applicano le regole 0 per numeri, false per booleani, stringa vuota per Stringhe. Per l’inizializzazione si usano le parentesi {} con i valori previsti separati da ,.

Per accedere al singolo elemento si specifica l’indice tra [], considerando che l’indice parte da 0.

Per conoscere quanti elementi contiene l’array Go mette a disposizione il comando len.

E’ possibile definire array multidimensionali specificando più volte le varie dimensioni sempre racchiuse tra [].

Il limite dell’array è che ha una dimensione fissa e non può essere esteso, quindi va usato in caso dove la dimensione è nota a priori, negli altri casi Go mette a disposizione il tipo slices.

Devo dire che lo slices come concetto è carico, esso supera i limiti dell’array appoggiandosi sempre ad un array che Go gestisce internamente.

Per instanziare lo slice si usa il comanda make che riceve in ingresso 3 parametri: il tipo di elementi, la lunghezza iniziale dello slices e la sua capacità. La capacità è opzionale ed in usa assenza verrà inizializzata con il valore della lunghezza.

Nell’esempio ho creato uno slice che non ha nessun elemento presente ma che prevede una capacità iniziale di 3 elementi, superati il quale Go estenderà in automatico. Tramite il ciclo for aggiungo in coda un elemento che Go farà senza problemi appoggiandosi ad un array virtualmente infinito. Infatti lo slice rappresenta una sezione di un array di sistema

Go permette anche di gestire lo slices a partire da un array definito dall’utente specificando gli indici separati da :, indici che possono essere opzionali e in loro assenza viene considerata l’intera sezione dell’array.

Ogni modifica fatta sullo slice sarà visibile sull’array e viceversa, proprio perchè lo slice rappresenta una vista su quell’array. Tramite il comando copy sarà possibile copiare il contenuto dello slice verso un altro slice.

Per poter ciclare su uno slice ci viene in comando il comando range che restituisce 2 valori : indice e copia del valore contenuto nella cella. i valori possono essere omessi se non di interesse usando la chiave _.

Infine affrontiamo il concetto di map, che è una struttura che rappresenta il concetto di chiave/valore, e vediamo le operazioni che su di essa si possono effettuare,

Definiamo la variabile mp come mappa con la chiave di tipo string e il valore string. Per instanziare la variabile usiamo il comando make. Per inserire un record usiamo l’espressione nomevariabile[nomechiave]= valore. Dopo aver inserito il record possiamo eliminarlo tramite il comando delete che in ingresso vuole la mappa e la chiave che definisce il record. Per leggere il valore si usa l’espressione nomevariabile[nomechiave] che restituisce 2 valori, il valore stesso e un boolean che indica se la chiave è stata trovata o meno. Nel caso in cui la chiave sia assente viene restituita una stringa vuota. Anche in questo caso possiamo usare la parola chiave range che ci restituisce per ogni record chiave e valore.

Alla prossima

TUTORIAL GO – TIPI COMPLESSI STRUCTS E POINTER

Nell’articolo precedente abbiamo visto i tipi semplici messi a disposizione da GO, in questo vediamo come definire delle strutture dati più complesse. Go mette a disposizione il comando type che consente di definire delle strutture, ovvero collezioni di dati

Tramite il comando type persona struct ho definito una struttura dati chiamata persona che presenta 2 attributi nome e cognome di tipo string. Nel main ho instanziato la variabile persona e valorizzato gli attributi opportunamente usando il . per accedere alle sue varibili. Go permette di inizializzare direttamente l’oggetto tramite il nome stesso della struttura passando direttamente i valori, oppure specificando i valori con la coppia nome valore separati da :.

Go supporta i puntatori, ovvero il riferimento a zone di memoria per accedere al valore contenuto in esso. I comandi per gestire i puntatori sono * e &.

Tramite * definisco un puntatore verso una struttura di tipo persona e tramite & la inizializzo verso la zona di memoria occupata dalla struttura io. A questo punto agisco su uno degli attributi di puntatoreame e vedrò le modifiche attive anche su io.

Il blocco successivo che non usa i puntatori crea una nuova variabile che ha gli stessi valori ma le modifiche che faccio successivamente non si ripercuotono sulla istanza io.

TUTORIAL GO – COSTRUTTI DI CONTROLLO

Oggi vediamo i costrutti di controllo offerti da GO. I costrutti consentono di configurare il flusso delle operazione sequenziali in base all’algoritmo stabilito dall’autore. Si dividono in iterativi e di selezione.

  • FOR

il costrutto for è un costrutto iterativo e consente di iterare un comando n volte fino a che è valida la condizione di controllo

nel ciclo for ho inizializzato la variabile i con 0 (Non ho esplicitato il tipo perchè Go lo desume da solo), ho definivo la condizione per continuare l’iterazione (i deve essere minore della costante limite) e ho definito la regola di incremento ( in questo caso i cresce di una unità per ogni iterazione). Rispetto ad altri linguaggi come java non sono richieste parentesi per chiudere i comandi di inizializzazione del for, mentre sono obbligatorie le parentesi {} per racchiudere il blocco di operazioni da effettuare.

La condizione di inizializzazione e la condizione di incremento sono opzionali, pertanto posso scrivere il codice in questo, rendendo il codice equivalente ad un costrutto while.

Anche la condizione di uscita può essere omessa, ottenendo così un ciclo virtualmente infinito che può essere pilotato tramite il comando break che interrompe l’esecuzione.

Insieme al comando break può essere usato il comando continue che permette di saltare l’iterazione corrente e andare alla prossima.

  • IF

Il costrutto IF è un costrutto di seleziona e consente di eseguire il codice contenuto nelle sue parentesi {} al verificare di una condizione booleana. Se guardate il codice precedente quando il contatore vale 5 il sistema interrompe il ciclo con il comando break.

Tramite il comando else è possibile definire un blocco di operazioni alternativo ed inoltre è possibile all’interno del blocco if definire una assegnazione ad una variabile che sarà visibile solo nel blocco if.

Nel blocco ho introdotto una variabile d inizializzata con il valore di z e ho definito una condizione alternativa a quella di uscita, grazie alla quale stampo il valore corrente dell’indice.

  • SWITCH

Il costrutto switch è un costrutto di selezione e ci viene in aiuto quando dobbiamo gestire la verifica di n possibili valori. Invece di usare tanti if/else annidati lo switch case ci consente di gestire in modo elegante la casistisca descritta.

Nel blocco sopra sto verificando il valore di z, gestendo le casistiche 1 e 2 con apposito output, per gli altri valori viene stampato il valore default. Quando la condizione viene riscontrata il sistema esegue il codice relativo, a differenza di altri linquaggi come JAVA non è necessario specificare la chiave break. Nella clausola case possono essere presenti più condizioni separate da virgola ed è possibile inserire l’output di una funzione, l’importante che il tipo sia dello stesso tipo delle altre clausole.

E’ possibile anche omettere la condizione da verificare ottenendo un modo più elegante per scrivere degli if/else in cascata specificando la regola di ingresso a livello del blocco case. Lo stesso codice di sopra può essere riscritto come segue

  • DEFER

Il costrutto DEFER è un comando interessante. Consente di eseguire un codice alla fine del programma. Agisce come una pila con una logica di tipo First In Last Out, pertanto il primo comando inserito sarà l’ultimo ad essere eseguito.

Ottenendo così l’output atteso

TUTORIAL GO – PACKAGE, TIPI, VARIABILI E COSTANTI

Messo in piedi l’IDE incominciamo a vedere come è strutturato il sorgente. Go è organizzato in package, quindi il primo comando definito all’interno del nostro file contiene la definizione del package tramite la direttiva package

Il package principale è main ed è quello da cui parte la nostra applicazione. Possiamo importare altri package per estendere le funzionalità a nostra disposizione e lo facciamo tramite la direttiva import. I package hanno la classica struttura ad albero, importante sapere che per invocare le funzioni all’interno del programma va usato l’ultimo nodo della definizione del package.

Nel codice sopra ho definito il package main, ho fatto l’import di 2 package di sistema e nella function main ho provveduto a stampare il risultato della chiamata random. Come potete vedere per invocare la funzione ho utilizzato l’ultima parte del nome del package rand.

L’elenco completo dei package di sistema è disponibile qui. L’import multiplo può essere fatto anche invocando più volte la direttiva import per ogni package ma così risulta più compatto.

A questo punto introduciamo le variabili, esse possono essere definite a livello di package o a livello di funzione, possono essere definite in modo esplicito tramite la chiave var e relativo tipo oppure lasciamo che sia Go a dedurre il tipo.

Nel blocco ho definito una variabile principale a livello di package tramite var e specificando il tipo, mentre ho definito una variabile secondaria a livello di function specificando direttamente il valore e lasciando decidere al compilatore la deduzione del tipo. L’operatore := può essere usato solo dentro una function.

Go mira alla stesura di codice compatto e permette la definizione di più variabili e relativa inizializzazione nello stesso statement.

I tipi semplici previsti da Go sono i sequenti:

Quando si definisce una variabile e non si specifica il valore il sistema inizializza con 0 i numeri, false i tipo bool e stringa vuota i tipi string. La conversione tra i tipi non è implicita ma deve essere gestita tramite l’opprtuna funzione.

Tramite l’operatore const è possibile definire delle costanti, se definite con lettera maiuscola saranno visibili al di fuori del package e dovranno presentare un commento a corredo

TUTORIAL GO – INSTALLARE GO

Iniziamo una serie di articoli dedicati a Go, il linguaggio opensource realizzato da Google e rilasciato nel 2009. Eletto nel 2009 e nel 2016 come linguaggio dell’anno da TIOBE.

Il sito ufficiale di Go è https://golang.org/

Per iniziare scarichiamo l’eseguibile disponibile nella sezione download https://golang.org/dl/ ed eseguendo la configurazione standard go creerà una cartella in C:\Go> e configurerà in automatico le variabili d’ambiente in modo che il compilatore sia invocabile in ogni shell.

Ad installazione finita basta lanciare il comando go version per verificare se tutto è ok. In caso positivo il sistema mostrerà la versione go installata nel mio caso

go version go1.14.6 windows/amd64

A questo punto apriamo il nostro ide. Allo stato attuale risultano 2 ide concorrenti Visual studio code di Microsoft e GoLang di JetBrains. GoLang è una suite pensata per Go ma è a pagamento, mentre Visual Studio Code è open source e tramite plugin supporta lo sviluppo per Go. Ho scelto Visual Studio Code e come plugin ho installato il plugin realizzato da Google disponibile qui.

A questo punto scriviamo il nostro primo programma in go e come classico dei classico scriviamo il nostro Ciao Mondo.

Creiamo la nostra directory e all’interno di essa creiamo il nostro file ciaamondo.go

la prima direttiva indica il package di appartenenza.

la seconda direttiva import permette di importare i package già offerti dalla piattaform, in questo fmt che consente di accedere alle funzioni di I/O.

Infine la funzione main che consente di scrivere a video il nostro messaggio.

Per lanciare il programma usiamo la direttiva run e il gioco è fatto

Per creare l’eseguibile usiamo la direttiva build che crea l’eseguibile.

Alla prossima.