Go-Sprache: Mehrdimensionale Arrays
Ein mehrdimensionales Array ist ein Array von Arrays. Betrachten Sie es als eineDatentabelleoderMatrix, wobei auf jedes Element über mehrere Indizes zugegriffen werden kann.
Mehrdimensionale Arrays in Go können verwendet werden, um strukturierte Informationen wie tabellarische Daten, Matrixoperationen oder Spielbretter zu verarbeiten.
Grundlegende Konzepte
- Eindimensionales Array: Wie Punkte auf einer Geraden, wird nur eine Koordinate (Index) benötigt, um ein bestimmtes Element zu finden.
- Zweidimensionales Array: wie eine Tabelle, erfordert zwei Koordinaten: Zeile und Spalte
- Dreidimensionales Array: wie ein Würfel, erfordert drei Koordinaten: Länge, Breite und Höhe
- Höhere Dimensionen: theoretisch können Arrays viele Dimensionen haben, aber in der Praxis werden zwei- und dreidimensionale Arrays am häufigsten verwendet
Dies lässt sich mit unseren alltäglichen Parkplätzen vergleichen:
- Eindimensionales Array= eine Reihe von Parkplätzen (man benötigt nur die Parkplatznummer)
- Zweidimensionales Array= ein mehrstöckiges Parkhaus (man benötigt die Etage und die Parkplatznummer)
- Dreidimensionales Array= mehrere mehrstöckige Parkhäuser (man benötigt die Parkhausnummer, die Etage und die Parkplatznummer)
Go unterstützt mehrdimensionale Arrays. Im Folgenden sind gängige Möglichkeiten zum Deklarieren mehrdimensionaler Arrays aufgeführt:
var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type
Deklaration und Initialisierung:
// Deklariere ein zweidimensionales Array var arrayName [rows][cols]elementType // Deklarieren und initialisieren var arrayName [rows][cols]elementType = [rows][cols]elementType{initialValues}Das folgende Beispiel deklariert ein dreidimensionales Integer-Array:
var threedim [5][10][4]int
Zweidimensionales Array
Ein zweidimensionales Array ist das einfachste mehrdimensionale Array. Ein zweidimensionales Array besteht im Wesentlichen aus eindimensionalen Arrays. Die Vorgehensweise zum Definieren eines zweidimensionalen Arrays ist wie folgt:
var arrayName [ x ][ y ] variable_type
variable_type ist der Datentyp in Go, arrayName ist der Array-Name. Ein zweidimensionales Array kann als Tabelle betrachtet werden, wobei x für die Zeilen und y für die Spalten steht. Das folgende Diagramm zeigt ein zweidimensionales Array a mit drei Zeilen und vier Spalten:

Auf Elemente in einem zweidimensionalen Array kann übera[ i ][ j ]zugegriffen werden.
Beispiel
import "fmt"
func main() {
// Schritt 1: Ein Array erstellen
values := [][]int{}
// Schritt 2: Verwende die Funktion append(), um einem leeren zweidimensionalen Array zwei Zeilen eindimensionaler Arrays hinzuzufügen
row1 := []int{1, 2, 3}
row2 := []int{4, 5, 6}
values = append(values, row1)
values = append(values, row2)
// Schritt 3: Zwei Datenzeilen anzeigen
fmt.Println("Zeile 1")
fmt.Println(values[0])
fmt.Println("Row 2")
fmt.Println(values[1])
// Schritt 4: Auf das erste Element zugreifen
fmt.Println("First element:")
fmt.Println(values[0][0])
}
Die Ausgabe des obigen Beispiels ist:
Row 1 [1 2 3] Row 2 [4 5 6] 第一个元素为: 1
Initialisieren eines zweidimensionalen Arrays
Mehrdimensionale Arrays können mit geschweiften Klammern initialisiert werden. Das folgende Beispiel ist ein zweidimensionales Array mit 3 Zeilen und 4 Spalten:
a := [3][4]int{
{0, 1, 2, 3} , /* 第一行索引为 0 */
{4, 5, 6, 7} , /* 第二行索引为 1 */
{8, 9, 10, 11}, /* 第三行索引为 2 */
}
Hinweis:Im obigen Code muss die vorletzte Zeile}ein Komma haben, weil die letzte Zeile}Es muss nicht in einer einzigen Zeile stehen; es kann auch so geschrieben werden:a := [3][4]int{
{0, 1, 2, 3} , /* 第一行索引为 0 */
{4, 5, 6, 7} , /* 第二行索引为 1 */
{8, 9, 10, 11}} /* 第三行索引为 2 */
Das folgende Beispiel initialisiert ein zweidimensionales Array mit 2 Zeilen und 2 Spalten:
Beispiel
import "fmt"
func main() {
// Ein zweidimensionales Array erstellen
sites := [2][2]string{}
// Elemente zum zweidimensionalen Array hinzufügen
sites[0][0] = "Google"
sites[0][1] = "Example"
sites[1][0] = "Taobao"
sites[1][1] = "Weibo"
// Ergebnis anzeigen
fmt.Println(sites)
}
Die Ausgabe des obigen Beispiels ist:
[[Google Example] [Taobao Weibo]]
Zugriff auf ein zweidimensionales Array
Auf ein zweidimensionales Array wird zugegriffen, indem Koordinaten angegeben werden, wie z. B. der Zeilenindex und der Spaltenindex im Array. Zum Beispiel:
val := a[2][3] oder var value int = a[2][3]
Im obigen Beispiel wurde auf das vierte Element in der dritten Zeile des zweidimensionalen Arrays val zugegriffen.
Ein zweidimensionales Array kann verschachtelte Schleifen verwenden, um Elemente auszugeben:
Beispiel
import "fmt"
func main() {
/* Array - 5 Zeilen 2 Spalten*/
var a = [5][2]int{ {0,0}, {1,2}, {2,4}, {3,6},{4,8}}
var i, j int
/* Array-Elemente ausgeben */
for i = 0; i < 5; i++ {
for j = 0; j < 2; j++ {
fmt.Printf("a[%d][%d] = %d\n", i,j, a[i][j] )
}
}
}
Die Ausgabe des obigen Beispiels ist:
a[0][0] = 0 a[0][1] = 0 a[1][0] = 1 a[1][1] = 2 a[2][0] = 2 a[2][1] = 4 a[3][0] = 3 a[3][1] = 6 a[4][0] = 4 a[4][1] = 8
Das folgende Beispiel erstellt ein mehrdimensionales Array, bei dem die Anzahl der Elemente in jeder Dimension unterschiedlich ist:
Beispiel
import "fmt"
func main() {
// Ein leeres zweidimensionales Array erstellen
animals := [][]string{}
// Drei eindimensionale Arrays mit jeweils unterschiedlicher Länge erstellen
row1 := []string{"Fisch", "Hai", "Aal"}
row2 := []string{"Vogel"}
row3 := []string{"Eidechse", "Salamander"}
// Verwende die append()-Funktion, um ein eindimensionales Array zum zweidimensionalen Array hinzuzufügen
animals = append(animals, row1)
animals = append(animals, row2)
animals = append(animals, row3)
// Schleife zur Ausgabe
for i := range animals {
fmt.Printf("Zeile: %v\n", i)
fmt.Println(animals[i])
}
}
Die Ausgabe des obigen Beispiels ist:
Row: 0 [fish shark eel] Row: 1 [bird] Row: 2 [lizard salamander]
Zugriff auf Array-Elemente und deren Änderung
Zugriff auf Elemente
Beispiel
import "fmt"
func main() {
// Erstelle eine 3x3-Matrix
matrix := [3][3]int{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
}
// Zugriff auf ein einzelnes Element
fmt.Println("Zeile 1, Spalte 2:", matrix[0][1]) // Ausgabe: 2
fmt.Println("Zeile 3, Spalte 3:", matrix[2][2]) // Ausgabe: 9
// Zugriff auf die gesamte Zeile
fmt.Println("Zeile 2:", matrix[1]) // Ausgabe: [4 5 6]
// Alle Elemente durchlaufen
fmt.Println("\nAlle Elemente durchlaufen:")
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
fmt.Printf("matrix[%d][%d] = %d\n", i, j, matrix[i][j])
}
}
}
Elemente ändern
Beispiel
import "fmt"
func main() {
// Eine 2x2-Nullmatrix erstellen
var grid [2][2]int
fmt.Println("Matrix vor der Änderung:", grid)
// Das Element an einer bestimmten Position ändern
grid[0][0] = 10
grid[0][1] = 20
grid[1][0] = 30
grid[1][1] = 40
fmt.Println("Matrix nach der Änderung:", grid)
// Eine Zeile batchweise ändern
grid[0] = [2]int{100, 200}
fmt.Println("Nach Änderung der ersten Zeile:", grid)
}
Drei- und höherdimensionale Arrays
Beispiel für ein dreidimensionales Array
Beispiel
import "fmt"
func main() {
// Ein dreidimensionales 2x3x4-Array deklarieren
// Kann verstanden werden als: 2 Ebenen, jede mit 3 Zeilen und 4 Spalten
var cube [2][3][4]int
// 3D-Array initialisieren
cube = [2][3][4]int{
{ // Die erste Ebene
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
},
{ // Die zweite Ebene
{13, 14, 15, 16},
{17, 18, 19, 20},
{21, 22, 23, 24},
},
}
// Zugriff auf 3D-Array-Elemente
fmt.Println("cube[0][1][2] =", cube[0][1][2]) // Ausgabe: 7
fmt.Println("cube[1][2][3] =", cube[1][2][3]) // Ausgabe: 24
// Ein 3D-Array durchlaufen
fmt.Println("\nInhalt des dreidimensionalen Arrays:)
for i := 0; i < 2; i++ {
fmt.Printf("Ebene %d:\n", i)
for j := 0; j < 3; j++ {
for k := 0; k < 4; k++ {
fmt.Printf("%3d ", cube[i][j][k])
}
fmt.Println()
}
fmt.Println()
}
}
siehe Abbildung unten:

Häufige Operationen mit mehrdimensionalen Arrays
1. Iterieren mit range
Beispiel
import "fmt"
func main() {
// Ein 2D-Array erstellen
scores := [3][4]int{
{85, 90, 78, 92},
{88, 76, 95, 89},
{92, 85, 88, 90},
}
fmt.Println("Notentabelle der Studierenden:")
// range verwenden, um über das 2D-Array zu iterieren
for i, row := range scores {
fmt.Printf("Noten von Student %d: ", i+1)
for j, score := range row {
fmt.Printf("%d ", score)
// Falls sowohl Index als auch Wert benötigt werden
_ = j // Warnung vor unbenutzter Variable vermeiden
}
fmt.Println()
}
// Nur den Wert berücksichtigen, nicht den Index
total := 0
count := 0
for _, row := range scores {
for _, score := range row {
total += score
count++
}
}
fmt.Printf("\nDurchschnittliche Punktzahl: %.2f\n", float64(total)/float64(count))
}
2. Die Array-Länge ermitteln
Beispiel
import "fmt"
func main() {
// Ein unregelmäßiges mehrdimensionales Array erstellen
jagged := [3][3]int{
{1, 2, 3},
{4, 5},
{6, 7, 8, 9}, // Hinweis: Dies führt zu einem Kompilierungsfehler, da jede Zeile dieselbe Länge haben muss
}
// Korrektes Beispiel: Array-Dimensionen ermitteln
matrix := [4][5]int{}
// Anzahl der Zeilen ermitteln
rows := len(matrix)
fmt.Println("Zeilen:", rows) // Ausgabe: 4
// Anzahl der Spalten in der ersten Zeile abrufen (alle Zeilen haben die gleiche Länge)
cols := len(matrix[0])
fmt.Println("Spalten:", cols) // Ausgabe: 5
// Gesamtzahl der Elemente abrufen
totalElements := rows * cols
fmt.Println("Gesamtzahl der Elemente:", totalElements) // Ausgabe: 20
}
3. Array-Vergleich
Beispiel
import "fmt"
func main() {
// Zwei identische 2D-Arrays erstellen
a := [2][2]int{{1, 2}, {3, 4}}
b := [2][2]int{{1, 2}, {3, 4}}
c := [2][2]int{{1, 2}, {3, 5}}
// Arrays können direkt verglichen werden (nur wenn die Dimensionen exakt gleich sind)
fmt.Println("a == b:", a == b) // Ausgabe: true
fmt.Println("a == c:", a == c) // Ausgabe: false
// Hinweis: Arrays unterschiedlicher Dimensionen können nicht verglichen werden
// d := [2][3]int{{1, 2, 3}, {4, 5, 6}}
// fmt.Println(a == d) // Kompilierfehler: Typen stimmen nicht überein
}
Praktische Anwendungsszenarien
Szenario 1: Spielbrett (Tic-Tac-Toe)
Beispiel
import "fmt"
func main() {
// Ein 3x3-Tic-Tac-Toe-Brett initialisieren
var board [3][3]string
// Als leer initialisieren
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
board[i][j] = " "
}
}
// Züge simulieren
board[0][0] = "X"
board[1][1] = "O"
board[2][2] = "X"
// Das Spielbrett ausgeben
fmt.Println("Tic-Tac-Toe-Brett:")
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
fmt.Printf(" %s ", board[i][j])
if j < 2 {
fmt.Printf("|")
}
}
fmt.Println()
if i < 2 {
fmt.Println("---+---+---")
}
}
}
Szenario 2: Notenverwaltungssystem für Studenten
Beispiel
import "fmt"
func main() {
// Definiere: 3 Studenten, jeder Student hat 4 Kurse
var grades [3][4]float64
// Eingabe der Punkte der Studenten
grades = [3][4]float64{
{85.5, 90.0, 78.5, 92.0}, // Punkte von Student 1
{88.0, 76.5, 95.0, 89.5}, // Punkte von Student 2
{92.5, 85.0, 88.5, 90.0}, // Punkte von Student 3
}
// Berechne die Durchschnittspunktzahl jedes Studenten
fmt.Println("Statistik der Studentenpunkte:")
for i, studentGrades := range grades {
sum := 0.0
for _, grade := range studentGrades {
sum += grade
}
average := sum / float64(len(studentGrades))
fmt.Printf("Student %d: Durchschnittsnote = %.2f\n", i+1, average)
}
// Berechne die Durchschnittsnote jedes Kurses
fmt.Println("\nKursdurchschnitt:")
for j := 0; j < 4; j++ {
sum := 0.0
for i := 0; i < 3; i++ {
sum += grades[i][j]
}
average := sum / 3.0
fmt.Printf("Kurs %d: Durchschnittsnote = %.2f\n", j+1, average)
}
}
Szenario 3: Bildpixelverarbeitung
Beispiel
import "fmt"
func main() {
// Ein einfaches 3x3-Graustufenbild simulieren
// Wertebereich jedes Pixels: 0(schwarz) ~ 255(weiß)
var image [3][3]int
// Das Bild initialisieren (ein einfacher Farbverlauf)
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
image[i][j] = (i + j) * 50
}
}
// Das Originalbild anzeigen
fmt.Println("Originalbild:")
displayImage(image)
// Bildverarbeitung: Helligkeit erhöhen
fmt.Println("\nBild nach Helligkeitserhöhung:")
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
// Helligkeit erhöhen, aber 255 nicht überschreiten
newValue := image[i][j] + 50
if newValue > 255 {
newValue = 255
}
image[i][j] = newValue
}
}
displayImage(image)
}
func displayImage(img [3][3]int) {
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
fmt.Printf("%3d ", img[i][j])
}
fmt.Println()
}
}
Hinweise und bewährte Verfahren
1. Array-Länge ist Teil des Typs
Beispiel
import "fmt"
func main() {
// Diese beiden sind unterschiedliche Typen!
var a [2][3]int
var b [3][2]int
// Der folgende Code verursacht einen Kompilierungsfehler
// a = b // Fehler: Typenkonflikt
fmt.Printf("Typ von a: %T\n", a) // [2][3]int
fmt.Printf("Typ von b: %T\n", b) // [3][2]int
}
2. Werttyp vs. Referenztyp
Beispiel
import "fmt"
func main() {
// Arrays sind Werttypen
original := [2][2]int{{1, 2}, {3, 4}}
// Eine Zuweisung erstellt eine Kopie
copy := original
// Das Ändern der Kopie wirkt sich nicht auf das ursprüngliche Array aus
copy[0][0] = 100
fmt.Println("Ursprüngliches Array:", original) // [[1 2] [3 4]]
fmt.Println("Kopiertes Array:", copy) // [[100 2] [3 4]]
// Wenn Sie Referenzsemantik benötigen, können Sie Slices verwenden (in späteren Artikeln eingeführt)
}
3. Leistungsüberlegungen
- Zusammenhängender Speicher: Mehrdimensionale Arrays werden zusammenhängend im Speicher abgelegt, was einen schnellen Zugriff ermöglicht
- Feste Größe: Die Länge eines Arrays wird zur Kompilierzeit festgelegt und kann nicht dynamisch geändert werden
- Geeignete Szenarien: Wenn die Datengröße bekannt und fest ist, sind Arrays die beste Wahl
Häufig gestellte Fragen
F1: Was ist der Unterschied zwischen einem mehrdimensionalen Array und einem verschachtelten Slice?
| Funktionen | Mehrdimensionale Arrays | Verschachtelte Slices |
|---|---|---|
| Size | Fest, zur Kompilierzeit festgelegt | Dynamisch, zur Laufzeit variabel |
| Gedächtnis | Zusammenhängende Allokation | Möglicherweise nicht zusammenhängend |
| Leistung | Schnelle Zugriffsgeschwindigkeit | Etwas langsamer, hat zusätzlichen Overhead |
| Anwendungsfall | Datengröße bekannt | Datengröße variabel |
F2: Wie erstellt man ein unregelmäßiges zweidimensionales Array?
Go-Arrays erfordern, dass jede Zeile die gleiche Länge hat. Wenn Sie eine unregelmäßige Struktur benötigen, sollten Sie Slices verwenden:
Beispiel
irregular := [][]int{
{1, 2, 3},
{4, 5}, // Diese Zeile hat nur 2 Elemente
{6, 7, 8, 9}, // Diese Zeile hat 4 Elemente
}
F3: Kann ein mehrdimensionales Array als Funktionsparameter verwendet werden?
Ja, aber beachten Sie, dass Arrays Werttypen sind und das Übergeben großer Arrays Leistungskosten verursacht:
Beispiel
// Die Matrix verarbeiten...
matrix[0][0] = 100
return matrix
}
// Ein besserer Weg ist die Verwendung von Pointern oder Slices
func processMatrixPtr(matrix *[3][3]int) {
matrix[0][0] = 100
}