Esercizio - Usare le matrici

Completato

Le matrici in Go sono una struttura di dati a lunghezza fissa di un determinato tipo. Possono avere zero o più elementi ed è necessario definirne le dimensioni al momento della dichiarazione o dell'inizializzazione. Non è inoltre possibile ridimensionarle dopo la creazione. Per questi motivi, le matrici non vengono comunemente usate nei programmi Go, ma rappresentano la base per slice e mappe.

Dichiarare le matrici

Per dichiarare una matrice in Go, è necessario definire il tipo di dati dei relativi elementi e il numero di elementi che la matrice può contenere. È quindi possibile accedere a ogni elemento nella matrice con la notazione con indice dove zero è il primo elemento e l'ultimo elemento ha un indice minore di uno rispetto alla lunghezza della matrice (lunghezza -1).

Ad esempio, si consideri il codice seguente:

package main

import "fmt"

func main() {
    var a [3]int
    a[1] = 10
    fmt.Println(a[0])
    fmt.Println(a[1])
    fmt.Println(a[len(a)-1])
}

Con l'esecuzione del codice precedente si ottiene questo output:

0
10
0

Anche se è stata dichiarata una matrice, non viene generato un errore quando si accede ai relativi elementi. Per impostazione predefinita, Go Inizializza ogni elemento con il tipo di dati predefinito. In questo caso, il valore predefinito per int è zero. È tuttavia possibile assegnare un valore a una posizione specifica, come si è fatto con a[1] = 10. È anche possibile accedere a tale elemento usando la stessa notazione. Si noti anche che per fare riferimento al primo elemento, è stato usato a[0]. Per fare riferimento all'ultimo elemento, è stato usato a[len(a)-1]. La funzione len è una funzione predefinita in Go per ottenere il numero di elementi in una matrice, una slice o una mappa.

Inizializzare le matrici

È anche possibile inizializzare una matrice con altri valori rispetto a quelli predefiniti quando si dichiara una matrice. Ad esempio, è possibile usare il codice seguente per visualizzare e testare la sintassi:

package main

import "fmt"

func main() {
    cities := [5]string{"New York", "Paris", "Berlin", "Madrid"}
    fmt.Println("Cities:", cities)
}

Con l'esecuzione del codice precedente si ottiene questo output:

Cities: [New York Paris Berlin Madrid ]

Anche se la matrice deve avere cinque elementi, non è necessario assegnare un valore a tutti gli elementi. Come è stato illustrato in precedenza, l'ultima posizione ha una stringa vuota perché si tratta del valore predefinito per un tipo di dati stringa.

Puntini di sospensione nelle matrici

Un altro modo per dichiarare e inizializzare una matrice quando non si conosce il numero di posizioni necessarie, ma si conosce il set di elementi dati, consiste nell'usare i puntini di sospensione (...), come illustrato nell'esempio seguente:

q := [...]int{1, 2, 3}

Il programma usato nella selezione precedente verrà ora modificato per usare i puntini di sospensione. Il codice avrà un aspetto simile all'esempio seguente:

package main

import "fmt"

func main() {
    cities := [...]string{"New York", "Paris", "Berlin", "Madrid"}
    fmt.Println("Cities:", cities)
}

Con l'esecuzione del codice precedente si dovrebbe ottenere un output simile, come in questo esempio:

Cities: [New York Paris Berlin Madrid]

La differenza è che non è presente una stringa vuota alla fine. La lunghezza della matrice è stata determinata dalle stringhe inserite al momento dell'inizializzazione. Non viene riservata memoria che non si sa se sarà necessaria.

Un altro modo interessante per inizializzare una matrice consiste nell'usare i puntini di sospensione e specificare solo un valore per l'ultima posizione. Ad esempio, usare il codice seguente:

package main

import "fmt"

func main() {
    numbers := [...]int{99: -1}
    fmt.Println("First Position:", numbers[0])
    fmt.Println("Last Position:", numbers[99])
    fmt.Println("Length:", len(numbers))
}

Con l'esecuzione del codice precedente si ottiene questo output:

First Position: 0
Last Position: -1
Length: 100

Si noti che la lunghezza della matrice è 100 perché è stato specificato un valore per la 99a posizione. La prima posizione stampa il valore predefinito (zero).

Matrici multidimensionali

Go supporta le matrici multidimensionali quando è necessario usare strutture di dati complesse. Verrà ora creato un programma in cui si dichiara e inizializza una matrice bidimensionale. Usare il codice seguente:

package main

import "fmt"

func main() {
    var twoD [3][5]int
    for i := 0; i < 3; i++ {
        for j := 0; j < 5; j++ {
            twoD[i][j] = (i + 1) * (j + 1)
        }
        fmt.Println("Row", i, twoD[i])
    }
    fmt.Println("\nAll at once:", twoD)
}

Eseguendo il programma precedente dovrebbe essere visualizzato un output simile al seguente:

Row 0 [1 2 3 4 5]
Row 1 [2 4 6 8 10]
Row 2 [3 6 9 12 15]

All at once: [[1 2 3 4 5] [2 4 6 8 10] [3 6 9 12 15]]

È stata dichiarata una matrice bidimensionale che specifica il numero di posizioni della matrice nella seconda dimensione, come questa var twoD [3][5]int. È possibile considerare questa matrice come una struttura di dati con colonne e righe, ad esempio un foglio di calcolo o una matrice. A questo punto, tutte le posizioni hanno il valore predefinito zero. Nel ciclo for ogni posizione viene inizializzata con un modello di valore diverso in ogni riga. Infine, vengono stampati tutti i relativi valori nel terminale.

E se si volesse dichiarare una matrice tridimensionale? La sintassi è facilmente intuibile. Questa operazione può essere eseguita come nell'esempio seguente:

package main

import "fmt"

func main() {
    var threeD [3][5][2]int
    for i := 0; i < 3; i++ {
        for j := 0; j < 5; j++ {
            for k := 0; k < 2; k++ {
                threeD[i][j][k] = (i + 1) * (j + 1) * (k + 1)
            }
        }
    }
    fmt.Println("\nAll at once:", threeD)
}

Eseguendo il codice precedente dovrebbe essere visualizzato un output simile al seguente:

All at once: [[[1 2] [2 4] [3 6] [4 8] [5 10]] [[2 4] [4 8] [6 12] [8 16] [10 20]] [[3 6] [6 12] [9 18] [12 24] [15 30]]]

Se si formatta l'output in modo più leggibile, si potrebbe ottenere un risultato simile a questo esempio:

All at once: 
[
    [
        [1 2] [2 4] [3 6] [4 8] [5 10]
    ] 
    [
        [2 4] [4 8] [6 12] [8 16] [10 20]
    ] 
    [
        [3 6] [6 12] [9 18] [12 24] [15 30]
    ]
]

Si noti come cambia la struttura rispetto a una matrice bidimensionale. È possibile continuare e aggiungere tutte le dimensioni necessarie. Nella prossima unità verranno però esplorati altri tipi di dati.