Verkettung von Slices in Go: Vom Anfänger zum Profi im Jahr 2025
Slices in Go sind dynamische Arrays, die das Herz der meisten Go-Anwendungen bilden. Früher oder später steht jeder Entwickler vor der Aufgabe: "Wie kombiniere ich zwei Slices zu einem?". Scheinbar eine triviale Operation, aber wie so oft in Go hat sie ihre Tücken und Leistungsnuancen.
Auf Stack Overflow hat diese Frage tausende Aufrufe erhalten, und das zu Recht: Eine suboptimale Verkettung kann zu unnötigen Speicherallokationen und einer Verlangsamung der Anwendungsgeschwindigkeit führen. In diesem Artikel analysieren wir alle legitimen Methoden, um zwei Slices zu verbinden – vom klassischen append bis zu den Neuerungen der Standardbibliothek von 2025 – und finden heraus, welche Methode je nach Situation die richtige ist.
Warum funktioniert einfaches Addieren nicht?
Im Gegensatz zu Python (list1 + list2) oder JavaScript (arr1.concat(arr2)) unterstützt Go den +-Operator nicht für Slices. Dies ist eine bewusste Entscheidung: Go ist eine Sprache, die Eindeutigkeit erfordert. Jede Operation mit Slices muss transparent sein, insbesondere im Hinblick auf die Speicherverwaltung.
Kommen wir direkt zur Sache. Hier ist die einfachste und gebräuchlichste Methode:
package main
import "fmt"
func main() { slice1 := []int{1, 2, 3} slice2 := []int{4, 5, 6}
// Methode Nr. 1: append mit Entpackung result := append(slice1, slice2...) fmt.Println(result) // [1 2 3 4 5 6]}Dieser Code funktioniert, hat aber eine Besonderheit. Wenn slice1 genügend Kapazität (cap) hat, ändert append ihn selbst und erstellt keinen neuen Slice. Dies kann zu unerwarteten Nebeneffekten führen, wenn Sie keine Mutation des ursprünglichen Slices erwarten.
Sichere Verkettung mit make + copy
Wenn Sie eine garantierte Unabhängigkeit des Ergebnisses von den ursprünglichen Slices benötigen, verwenden Sie die Kombination aus make und copy. Dies ist der "Goldstandard" zum Erstellen eines neuen Slices ohne Risiko, das Original zu verändern.
func concatSlices[T any](a, b []T) []T { result := make([]T, len(a)+len(b)) copy(result, a) copy(result[len(a):], b) return result}
// Verwendung:combined := concatSlices(slice1, slice2)Warum ist das gut?
- Vorhersagbarkeit: Sie erstellen immer einen neuen Slice. Die ursprünglichen Daten bleiben unberührt.
- Kontrolle: Sie weisen Speicher explizit einmal zu, anstatt sich auf die interne Logik von
appendzu verlassen. - Generics (Go 1.18+): Die Funktion funktioniert mit jedem Datentyp.
Moderner Ansatz: slices.Concat (Go 1.22+)
Ab der Go-Version 1.22 (die bis 2025 längst zum Standard geworden ist) gibt es im Paket golang.org/x/exp/slices die Funktion Concat. In Go 1.22 wurde sie in die Standardbibliothek übernommen.
Dies ist die offizielle, empfohlene Methode zur Verkettung, die die Sicherheit von copy mit der Prägnanz von append vereint.
import "slices"
func main() { a := []string{"Go", "Python", "Rust"} b := []string{"JavaScript", "TypeScript"}
combined := slices.Concat(a, b) // combined = ["Go", "Python", "Rust", "JavaScript", "TypeScript"]}Vorteile von slices.Concat:
- Lesbarkeit: Der Name spricht für sich. Der Code wird deklarativ.
- Optimierung: Intern wird eine effiziente Allokation und
copyverwendet. - Flexibilität: Sie können beliebig viele Slices übergeben:
slices.Concat(s1, s2, s3, s4).
Wenn Sie Code mit Go 1.22+ schreiben (und das ist 2025 der Mainstream), verwenden Sie getrost slices.Concat. Dies ist die beste Wahl für 90% der Aufgaben.
Wann wird append noch benötigt?
Klassisch