Iteration über einen Zahlenbereich in Go: 3 leistungsstarke Ansätze

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Warum ist die Frage "Is there a way to iterate over a range of integers?" so beliebt?

\n\n

Wenn Sie jemals von Python zu Go gekommen sind, erinnern Sie sich sicher an das elegante for i in range(10):. In Python funktioniert das wie am Schnürchen. In Go... ist alles etwas anders. Die Frage auf Stack Overflow mit diesem Titel hat Tausende von Aufrufen gesammelt – und das ist kein Zufall. Entwickler, die an High-Level-Abstraktionen gewöhnt sind, sind oft verwirrt, wenn sie auf die minimalistische Syntax von Go stoßen.

\n\n

In diesem Artikel werden wir alle Möglichkeiten der Iteration über einen Bereich von ganzen Zahlen in Go durchgehen: vom klassischen for bis zu modernen Hilfsprogrammen. Sie erfahren, welcher Ansatz für maximale Leistung und welcher für die Lesbarkeit des Codes zu wählen ist. Los geht's!

\n\n

Methode Nr. 1: Klassisches for (idiomatisches Go)

\n\n

Go ist eine Sprache der Pragmatiker. Es gibt kein eingebautes range für Zahlen, aber es gibt ein leistungsstarkes for. Der einfachste und leistungsfähigste Weg ist die Verwendung einer Dreikomponenten-Schleife:

\n\n
package main\n\nimport "fmt"\n\nfunc main() {\n    // Iteration von 0 bis 9 (insgesamt 10 Elemente)\n    for i := 0; i < 10; i++ {\n        fmt.Println(i)\n    }\n}
\n\n

Dieser Code ist maximal effizient: Der Compiler wandelt ihn in eine einfache Registererhöhung um. Keine Speicherzuweisungen, kein Overhead. So schreiben Go-Entwickler im Produktivbetrieb.

\n\n

Varianten des klassischen for

\n\n

Sie können den Startwert und die Schrittweite leicht ändern:

\n\n
// Von 5 bis 15\nfor i := 5; i <= 15; i++ {\n    fmt.Println(i)\n}\n\n// Nur gerade Zahlen von 0 bis 20\nfor i := 0; i <= 20; i += 2 {\n    fmt.Println(i)\n}\n\n// Umgekehrte Reihenfolge: von 10 bis 1\nfor i := 10; i >= 1; i-- {\n    fmt.Println(i)\n}
\n\n

Dieser Ansatz ist der Goldstandard für die Iteration über einen Zahlenbereich in Go. Er ist einfach, verständlich und erfordert keinen Import zusätzlicher Pakete.

\n\n

Methode Nr. 2: Verwendung von range mit einem Slice (für Python-Liebhaber)

\n\n

Wenn Sie den Python-Stil sehr vermissen, können Sie einen Slice erstellen und mit range darüber iterieren. Aber seien Sie vorsichtig: Dies beeinträchtigt die Leistung erheblich.

\n\n
package main\n\nimport "fmt"\n\nfunc main() {\n    // Erstellen eines Slices mit Zahlen von 0 bis 9\n    numbers := make([]int, 10)\n    for i := range numbers {\n        numbers[i] = i\n    }\n\n    // Jetzt verwenden wir range für die Iteration\n    for _, num := range numbers {\n        fmt.Println(num)\n    }\n}
\n\n

Warum ist das schlecht? Speicherzuweisung. Jedes Mal, wenn Sie einen Slice erstellen, weist Go Speicher auf dem Heap zu. Für einen Bereich von 10 Elementen ist das unbemerkt, aber für 10 Millionen ist es bereits ein Problem.

\n\n

Benchmark: for vs. range mit Slice

\n\n

Schauen wir uns die Zahlen an (Iteration über 1.000.000 Zahlen):

\n\n
    \n
  • Klassisches for: ~2,5 ms, 0 Zuweisungen
  • \n
  • Range mit Slice: ~45 ms, 1 Zuweisung (8 MB)
  • \n
\n\n

Ein Unterschied von 18 Mal! Und das nur für eine Million Elemente. Bei größeren Bereichen wird die Lücke nur noch größer.

\n\n

Methode Nr. 3: Verwendung von Bibliotheken (iter, lo und andere)

\n\n

Die Go-Community steht nicht still. Es gibt Drittanbieter-Bibliotheken, die syntaktischen Zucker für die Iteration über einen Bereich hinzufügen. Betrachten wir zwei beliebte:

\n\n

3.1 Paket iter (experimentell, Go 1.23+)

\n\n

Ab Go 1.23 gibt es in der Standardbibliothek ein experimentelles Paket iter, mit dem Sie Iteratoren erstellen können. Es ist noch nicht stabil, aber bereits verfügbar:

\n\n
package main\n\nimport (\n    "fmt"\n    "iter"\n)\n\nfunc main() {\n    // Erstellen eines Iterators von 0 bis 9\n    seq := iter.Seq[int](func(yield func(int) bool) {\n        for i := 0; i < 10; i++ {\n            if !yield(i) {\n                return\n            }\n        }\n    })\n\n    for num := range seq {\n        fmt.Println(num)\n    }\n}
\

Blogs

Buchempfehlungen