Ćwiczenie — używanie tablic

Ukończone

Tablice w języku Go to struktura danych o stałej długości określonego typu. Mogą mieć zero lub więcej elementów i trzeba zdefiniować rozmiar podczas deklarowania lub inicjowania. Ponadto nie można zmienić ich rozmiaru po ich utworzeniu. Z tych powodów tablice nie są często używane w programach Języka Go, ale stanowią podstawę wycinków i map.

Deklarowanie tablic

Aby zadeklarować tablicę w języku Go, należy zdefiniować typ danych jego elementów i liczbę elementów, które może pomieścić tablica. Następnie można uzyskać dostęp do każdego elementu w tablicy z notacją w indeksie dolnym, gdzie zero jest pierwszym elementem, a ostatni element jest o jedną mniejszą niż długość tablicy (długość — 1).

Na przykład użyjemy następującego kodu:

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])
}

Po uruchomieniu poprzedniego kodu uzyskasz następujące dane wyjściowe:

0
10
0

Mimo że zadeklarowaliśmy tablicę, nie występuje błąd podczas uzyskiwania dostępu do jej elementów. Domyślnie język Go inicjuje każdy element z domyślnym typem danych. W tym przypadku wartość domyślna parametru int to zero. Można jednak przypisać wartość do określonej pozycji, tak jak w przypadku a[1] = 10polecenia . Dostęp do tego elementu można uzyskać przy użyciu tej samej notacji. Zwróć również uwagę, że aby odwołać się do pierwszego elementu, użyliśmy elementu a[0]. Aby odwołać się do ostatniego elementu, użyliśmy polecenia a[len(a)-1]. Funkcja len jest wbudowaną funkcją w języku Go, aby uzyskać liczbę elementów w tablicy, wycinku lub mapie.

Inicjowanie tablic

Można również zainicjować tablicę z innymi wartościami niż domyślne podczas deklarowania tablicy. Na przykład możesz użyć następującego kodu, aby wyświetlić i przetestować składnię:

package main

import "fmt"

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

Uruchom powyższy kod i powinny zostać wyświetlone następujące dane wyjściowe:

Cities: [New York Paris Berlin Madrid ]

Mimo że tablica powinna zawierać pięć elementów, nie musimy przypisywać wartości do wszystkich elementów. Jak widzieliśmy wcześniej, ostatnia pozycja ma pusty ciąg, ponieważ jest to wartość domyślna dla typu danych ciągu.

Wielokropek w tablicach

Innym sposobem deklarowania i inicjowania tablicy, gdy nie wiesz, ile pozycji potrzebujesz, ale znasz zestaw elementów danych, jest użycie wielokropka (...), takiego jak w tym przykładzie:

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

Zmodyfikujmy program użyty w poprzedniej sekcji, aby użyć wielokropka. Kod powinien wyglądać następująco:

package main

import "fmt"

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

Uruchom powyższy kod i powinny zostać wyświetlone podobne dane wyjściowe, takie jak w poniższym przykładzie:

Cities: [New York Paris Berlin Madrid]

Czy widzisz różnicę? Na końcu nie ma pustego ciągu. Długość tablicy została określona przez ciągi wprowadzone podczas jego inicjowania. Nie zastrzegasz sobie pamięci, nie wiesz, czy skończysz potrzebować.

Innym interesującym sposobem inicjowania tablicy jest użycie wielokropka i określenie wartości tylko dla ostatniej pozycji. Na przykład użyj następującego kodu:

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))
}

Uruchom ten kod i uzyskasz następujące dane wyjściowe:

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

Zwróć uwagę, że długość tablicy wynosi 100, ponieważ określono wartość dla 99. pozycji. Pierwsze położenie drukuje wartość domyślną (zero).

Tablice wielowymiarowe

Środowisko Go obsługuje tablice wielowymiarowe, gdy trzeba pracować ze złożonymi strukturami danych. Utwórzmy program, w którym deklarujesz i inicjujesz tablicę dwuwymiarową. Użyj następującego kodu:

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)
}

Uruchom poprzedni program i powinny zostać wyświetlone dane wyjściowe podobne do tego przykładu:

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]]

Zadeklarowaliśmy tablicę dwuwymiarową, która określa, ile pozycji tablica będzie miała w drugim wymiarze, na przykład w tym .var twoD [3][5]int Tę tablicę można traktować jako jedną strukturę danych z kolumnami i wierszami, takimi jak arkusz kalkulacyjny lub macierz. W tym momencie wszystkie pozycje mają domyślną wartość zero. W pętli inicjujemy for każdą pozycję z innym wzorcem wartości w każdym wierszu. Na koniec wyświetlisz wszystkie jego wartości w terminalu.

Co zrobić, jeśli chcesz zadeklarować tablicę trójwymiarową? Cóż, możesz odgadnąć, jaka byłaby składnia, prawda? Możesz to zrobić w następujący przykład:

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)
}

Uruchom powyższy kod i powinny zostać wyświetlone dane wyjściowe podobne do tego przykładu:

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]]]

Jeśli formatujemy dane wyjściowe w bardziej czytelnym formacie, możesz mieć coś takiego jak w tym przykładzie:

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]
    ]
]

Zwróć uwagę, że struktura zmienia się z tablicy dwuwymiarowej. W miarę potrzeb możesz nadal mieć więcej wymiarów, ale na razie pozostawimy go tutaj, ponieważ mamy inne typy danych do zbadania.