1 Introduzione ai tipi di dati del linguaggio Go
Nel linguaggio Go, i tipi di dati sono la base della programmazione e determinano la forma dei dati che le variabili possono memorizzare. I tipi di dati di base forniti dal linguaggio Go sono principalmente divisi nelle seguenti categorie:
Tipo di Dato | Descrizione | Utilizzo di memoria |
---|---|---|
bool | Tipo booleano, utilizzato per memorizzare vero o falso | 1 byte |
int, uint | Intero con segno e senza segno, la dimensione predefinita dipende dalla piattaforma del sistema | 4 o 8 byte |
int8, uint8 | Interi con segno e senza segno a 8 bit | 1 byte |
int16, uint16 | Interi con segno e senza segno a 16 bit | 2 byte |
int32, uint32 | Interi con segno e senza segno a 32 bit | 4 byte |
int64, uint64 | Interi con segno e senza segno a 64 bit | 8 byte |
float32 | Numero in virgola mobile a 32 bit | 4 byte |
float64 | Numero in virgola mobile a 64 bit | 8 byte |
complex64 | Numero complesso con parti reali e immaginarie a 32 bit | 8 byte |
complex128 | Numero complesso con parti reali e immaginarie a 64 bit | 16 byte |
byte | Simile a uint8 | 1 byte |
rune | Simile a int32, rappresenta un punto codice Unicode | 4 byte |
string | Tipo stringa | Dipende dalla lunghezza della stringa |
error | Interfaccia di errore, utilizzata per restituire informazioni sull'errore | Nessuna dimensione fissa |
Questi tipi possono essere scelti in base alle diverse esigenze, come calcoli numerici, elaborazione del testo o controllo logico.
2 Tipi di Dati Integer
2.1 Panoramica dei Tipi Integer
Il linguaggio Go ha diversi tipi di interi incorporati, classificati come segue:
- Interi con segno:
int8
,int16
,int32
(orune
),int64
eint
- Interi senza segno:
uint8
(obyte
),uint16
,uint32
,uint64
euint
Le dimensioni di int
e uint
sono di 4 byte su sistemi a 32 bit e di 8 byte su sistemi a 64 bit. Gli intervalli di valori dei tipi di dati integer sono mostrati nella seguente tabella:
Tipo | Intervallo di Valori |
---|---|
int8 | -128 a 127 |
uint8 | 0 a 255 |
int16 | -32768 a 32767 |
uint16 | 0 a 65535 |
int32 | -2147483648 a 2147483647 |
uint32 | 0 a 4294967295 |
int64 | -9223372036854775808 a 9223372036854775807 |
uint64 | 0 a 18446744073709551615 |
2.2 Uso delle Variabili Integer
La sintassi di base per dichiarare una variabile intera è la seguente:
var nome_variabile tipo_dati = valore_iniziale
Esempio di codice:
package main
import "fmt"
func main() {
var a int = 10 // Variabile intera con segno
var b uint = 20 // Variabile intera senza segno
var c int8 = -128 // Valore int8 più piccolo
fmt.Println(a, b, c)
}
2.3 Operazioni Integer
Il linguaggio Go supporta operatori aritmetici comuni, come l'addizione (+
), la sottrazione (-
), la moltiplicazione (*
), la divisione (/
) e il modulo (%
), nonché operatori bitwise come AND bitwise (&
), OR (|
), XOR (^
), spostamento a sinistra (<<
) e spostamento a destra (>>
).
package main
import "fmt"
func main() {
x := 10
y := 3
// Operazioni aritmetiche
fmt.Println(x + y) // Addizione
fmt.Println(x - y) // Sottrazione
fmt.Println(x * y) // Moltiplicazione
fmt.Println(x / y) // Divisione
fmt.Println(x % y) // Modulo
// Operazioni bitwise
fmt.Println(x & y) // AND bitwise
fmt.Println(x | y) // OR bitwise
fmt.Println(x ^ y) // XOR bitwise
fmt.Println(x << 1) // Spostamento a sinistra di 1
fmt.Println(x >> 1) // Spostamento a destra di 1
}
3 Tipi di Dati Floating Point
3.1 Panoramica dei Tipi di Dati Floating Point
Nel linguaggio Go, i tipi di dati floating point includono float32
e float64
, corrispondenti a dati floating point a 32 bit e 64 bit. In generale, si consiglia di utilizzare float64
poiché fornisce un intervallo maggiore e una precisione più accurata.
-
float32
ha approssimativamente 23 bit significativi, fornendo circa 7 cifre decimali di precisione. -
float64
ha approssimativamente 52 bit significativi, fornendo circa 16 cifre decimali di precisione.
3.2 Utilizzo delle Variabili Floating Point
Le variabili floating point possono essere dichiarate fornendo letterali diretti o utilizzando la parola chiave var
:
package main
import "fmt"
func main() {
var f1 float32 = 3.14 // Specificare esplicitamente il tipo float32
f2 := 3.14 // Inference automatica come tipo float64
fmt.Println(f1, f2)
}
3.3 Aritmetica Floating Point e Problemi
L'aritmetica floating point può portare a perdita di precisione. Eseguire operazioni con precisione molto alta è un problema comune, specialmente quando si sottraggono due numeri molto vicini.
package main
import "fmt"
func main() {
f1 := .1
f2 := .2
f3 := f1 + f2
fmt.Println(f3) // L'output potrebbe non essere il .3 atteso a causa di problemi di precisione
// Risoluzione dei problemi di precisione utilizzando l'output formattato
fmt.Printf("%.1f\n", f3) // Output corretto a .3
}
4 Tipo di Dati Booleano
4.1 Panoramica del Tipo di Dati Booleano
Il booleano è il tipo di dato più semplice e può avere solo due valori: true
(vero) e false
(falso). Ricopre una posizione molto importante nelle istruzioni condizionali e nelle strutture di controllo del loop.
4.2 Utilizzo delle Variabili Booleane
Dichiarazione e utilizzo delle variabili booleane:
package main
import "fmt"
func main() {
var success bool = true
var fail bool = false
fmt.Println("Operazione riuscita:", success)
fmt.Println("Operazione fallita:", fail)
}
I valori booleani sono spesso utilizzati nelle istruzioni condizionali:
package main
import "fmt"
func main() {
a := 10
b := 20
fmt.Println("a == b:", a == b) // false
fmt.Println("a < b:", a < b) // true
}
5 Tipo di Dati Stringa
5.1 Panoramica della Stringa
Una stringa è una collezione di caratteri. Nel linguaggio Go, le stringhe sono immutabili. Ogni stringa è composta da due parti: un puntatore all'array di byte sottostante e una lunghezza. Le stringhe possono contenere qualsiasi dato, inclusi byte.
5.2 Utilizzo delle Variabili Stringa
Le variabili stringa sono generalmente dichiarate usando doppi apici "
per crearle, ma è anche possibile utilizzare il backtick ` per creare stringhe multilinea:
package main
import "fmt"
func main() {
var s1 string = "ciao"
s2 := "mondo"
s3 := `Questa è una
stringa su
più linee`
fmt.Println(s1)
fmt.Println(s2)
fmt.Println(s3)
}
Una volta creata una stringa, il suo contenuto non può essere modificato. L'operazione seguente è illegale e provocherà un errore di compilazione:
s := "ciao"
s[] = 'C` // Errore di compilazione: il contenuto delle stringhe è immutabile
5.3 Operazioni sulle Stringhe
Le stringhe sono molto comuni e importanti nella programmazione. Il linguaggio Go fornisce un ricco insieme di funzioni incorporate per la manipolazione delle stringhe. Ecco alcune operazioni comunemente utilizzate.
5.3.1 Concatenazione delle Stringhe
Nel linguaggio Go, è possibile utilizzare l'operatore più (+
) per concatenare le stringhe, che è il metodo più diretto. Inoltre, quando si tratta di frequenti concatenazioni di stringhe multiple, è consigliabile utilizzare strings.Builder
per prestazioni migliori.
package main
import (
"fmt"
"strings"
)
func main() {
// Concatenazione delle stringhe usando +
ciao := "Ciao, "
mondo := "Mondo!"
risultato := ciao + mondo
fmt.Println(risultato) // Output: Ciao, Mondo!
// Concatenazione delle stringhe usando strings.Builder
var sb strings.Builder
sb.WriteString("Ciao, ")
sb.WriteString("Mondo!")
fmt.Println(sb.String()) // Output: Ciao, Mondo!
}
5.3.2 Divisione delle stringhe
La divisione delle stringhe può essere fatta utilizzando la funzione strings.Split
, che suddivide la stringa in una slice in base al delimitatore specificato.
package main
import (
"fmt"
"strings"
)
func main() {
// Definire una stringa
frase := "Go è un linguaggio di programmazione open source"
// Suddividi la stringa per spazio
parole := strings.Split(frase, " ")
for _, parola := range parole {
fmt.Printf("%s\n", parola)
}
// Output:
// Go
// è
// un
// linguaggio
// di
// programmazione
// open
// source
}
5.3.3 Accesso all'indice
In Go, una stringa è una sequenza immutabile di byte. È possibile utilizzare l'indicizzazione per accedere a byte specifici all'interno di una stringa. Tuttavia, è importante notare che poiché una stringa può contenere caratteri multibyte (come caratteri codificati in UTF-8), l'indicizzazione diretta potrebbe non restituire il singolo carattere atteso.
package main
import "fmt"
func main() {
s := "Ciao, mondo"
for i := 0; i < len(s); i++ {
fmt.Printf("%d: %x\n", i, s[i])
}
// Nota: ciò restituirà la rappresentazione esadecimale dei byte, non dei caratteri
}
Per iterare attraverso la stringa per carattere, è possibile utilizzare il ciclo range
.
package main
import "fmt"
func main() {
s := "Ciao, mondo"
for indice, valoreRune := range s {
fmt.Printf("%d: %U '%c'\n", indice, valoreRune, valoreRune)
}
// Output: indice, codifica Unicode e il carattere stesso per ciascun carattere
}
5.3.4 Ottenere la lunghezza
La funzione len
può ottenere la lunghezza di una stringa, ovvero la lunghezza della sequenza di byte sottostante. Per le stringhe UTF-8, se è necessario ottenere il numero di caratteri (rune), è necessario utilizzare la funzione utf8.RuneCountInString
. Questo gestisce correttamente i caratteri multibyte.
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
s := "Ciao, mondo"
fmt.Println("Lunghezza dei byte:", len(s)) // Output della lunghezza dei byte
fmt.Println("Lunghezza dei rune:", utf8.RuneCountInString(s)) // Output della lunghezza dei caratteri
}
Dall'esempio precedente, possiamo vedere che il linguaggio Go fornisce ricche funzioni di libreria per le operazioni sulle stringhe, rendendo facile completare varie attività di elaborazione delle stringhe. Durante la scrittura del codice, è importante prestare attenzione alla distinzione tra byte e caratteri, specialmente quando si lavora con set di caratteri non ASCII.