web-dev-qa-db-de.com

Verketten Sie zwei Slices in Go

Ich versuche, den Slice [1, 2] und den Slice [3, 4] zu kombinieren. Wie kann ich das in Go machen?

Ich habe es versucht:

append([]int{1,2}, []int{3,4})

aber bekam:

cannot use []int literal (type []int) as type int in append

Die Dokumentation scheint jedoch darauf hinzuweisen, dass dies möglich ist. Was fehlt mir?

slice = append(slice, anotherSlice...)
307
Kevin Burke

Fügen Sie nach dem zweiten Schnitt Punkte hinzu:

//---------------------------vvv
append([]int{1,2}, []int{3,4}...)

Dies ist wie bei jeder anderen variadischen Funktion.

func foo(is ...int) {
    for i := 0; i < len(is); i++ {
        fmt.Println(is[i])
    }
}

func main() {
    foo([]int{9,8,7,6,5}...)
}
531
user1106925

Anfügen und Kopieren von Slices

Die variadische Funktion append hängt null oder mehr Werte x an s.__ an. vom Typ S, der ein Slice-Typ sein muss, und gibt das resultierende .__ zurück. Slice, auch vom Typ S. Die Werte x werden an einen Parameter von .__ übergeben. type ...T Dabei ist T der Elementtyp von S und das jeweilige Es gelten die Parameterübergaberegeln. Als Sonderfall akzeptiert append auch ein erstes Argument, das dem Typ []byte zugeordnet werden kann, mit einem zweiten Argument von string type gefolgt von .... Dieses Formular hängt die Bytes von .__ an. Schnur.

append(s S, x ...T) S  // T is the element type of S

s0 := []int{0, 0}
s1 := append(s0, 2)        // append a single element     s1 == []int{0, 0, 2}
s2 := append(s1, 3, 5, 7)  // append multiple elements    s2 == []int{0, 0, 2, 3, 5, 7}
s3 := append(s2, s0...)    // append a slice              s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}

Argumente an ... Parameter übergeben

Wenn f vom endgültigen Parametertyp ...T abweichend ist, dann innerhalb von Funktion Das Argument entspricht einem Parameter vom Typ []T. Beim Bei jedem Aufruf von f ist das an den endgültigen Parameter übergebene Argument ein neuer Slice vom Typ []T, dessen aufeinanderfolgende Elemente die tatsächlichen Argumente sind, wobei alle dem Typ T zuordenbar sein müssen. Die Länge der Scheibe beträgt daher die Anzahl der Argumente, die an den endgültigen Parameter gebunden sind, und kann unterscheiden sich für jede Anrufseite.

Die Antwort auf Ihre Frage ist das Beispiel s3 := append(s2, s0...) in der Go-Programmiersprache-Spezifikation . Zum Beispiel,

s := append([]int{1, 2}, []int{3, 4}...)
57
peterSO

Nichts gegen die anderen Antworten, aber ich fand die kurze Erklärung in the docs leichter verständlich als die Beispiele darin:

func anhängen

func append(slice []Type, elems ...Type) []Type Das integrierte Anhängen Funktion hängt Elemente an das Ende eines Slice an. Wenn es ausreichend ist Kapazität wird das Ziel erneut zugeschnitten, um die neuen Elemente aufzunehmen . Ist dies nicht der Fall, wird ein neues zugrundeliegendes Array zugewiesen. Anhängen gibt das aktualisierte Slice zurück. Es ist daher notwendig, das .__ zu speichern. Ergebnis von append, oft in der Variable, die das Slice selbst enthält:

slice = append(slice, elem1, elem2)
slice = append(slice, anotherSlice...)

Als Sonderfall ist es zulässig, einen String an ein Byte-Segment anzuhängen so was:

slice = append([]byte("hello "), "world"...)
23
fiatjaf

Ich denke, es ist wichtig, darauf hinzuweisen und zu wissen, dass das Anfügen "in-place" erfolgt, wenn das Ziel-Slice (das Slice, an das Sie anhängen) ausreichend Kapazität hat, indem Sie das Ziel erneut lizensieren (Reslicing auf Zunahme seine Länge, um die anhängbaren Elemente aufnehmen zu können).

Dies bedeutet, dass das Ziel möglicherweise überschrieben wird, wenn das Ziel durch Schneiden eines größeren Arrays oder Slice erstellt wurde, das über die Länge des resultierenden Slice hinaus weitere Elemente enthält.

Zur Veranschaulichung siehe folgendes Beispiel:

a := [10]int{1, 2}
fmt.Printf("a: %v\n", a)

x, y := a[:2], []int{3, 4}
fmt.Printf("x: %v, y: %v\n", x, y)
fmt.Printf("cap(x): %v\n", cap(x))

x = append(x, y...)
fmt.Printf("x: %v\n", x)

fmt.Printf("a: %v\n", a)

Ausgabe (probiere es auf dem Go Playground ):

a: [1 2 0 0 0 0 0 0 0 0]
x: [1 2], y: [3 4]
cap(x): 10
x: [1 2 3 4]
a: [1 2 3 4 0 0 0 0 0 0]

Wir haben ein "backing" -Array a mit der Länge 10 erstellt. Dann erstellen wir das Ziel x Ziel, indem wir dieses a Array in Scheiben schneiden. y Slice wird mit dem zusammengesetzten Literal []int{3, 4} erstellt. Wenn wir nun y an x anhängen, ist das Ergebnis der erwartete [1 2 3 4], aber überraschend ist, dass sich auch das Backing-Array a geändert hat, weil die Kapazität von x ist 10 reicht aus, um y an dieses anzuhängen, so dass x erneut lizenziert wird, das dasselbe a Backing-Array verwendet, und append() kopiert Elemente von y dorthin.

Wenn Sie dies vermeiden möchten, können Sie einen Full Slice-Ausdruck verwenden, der die Form hat

a[low : high : max]

dadurch wird ein Slice erstellt und auch die Kapazität des resultierenden Slices gesteuert, indem es auf max - low gesetzt wird.

Siehe das modifizierte Beispiel (der einzige Unterschied besteht darin, dass wir x wie folgt erstellen: x = a[:2:2]:

a := [10]int{1, 2}
fmt.Printf("a: %v\n", a)

x, y := a[:2:2], []int{3, 4}
fmt.Printf("x: %v, y: %v\n", x, y)
fmt.Printf("cap(x): %v\n", cap(x))

x = append(x, y...)
fmt.Printf("x: %v\n", x)

fmt.Printf("a: %v\n", a)

Ausgabe (probiere es auf dem Go Playground )

a: [1 2 0 0 0 0 0 0 0 0]
x: [1 2], y: [3 4]
cap(x): 2
x: [1 2 3 4]
a: [1 2 0 0 0 0 0 0 0 0]

Wie Sie sehen, erhalten wir dasselbe x Ergebnis, aber das Hintergrundarray a hat sich nicht geändert, da die Kapazität von x "nur" 2 war (dank des vollständigen Slice-Ausdrucks a[:2:2]). . Für das Anfügen wird also ein neues Backing-Array zugewiesen, das die Elemente von x und y speichern kann, die sich von a unterscheiden.

18
icza

append () - Funktion und Spread-Operator

Zwei Slices können mithilfe derappend- Methode in der Standardgolang-Bibliothek verkettet werden. Welches ist ähnlich der variadic Funktionsoperation. Also müssen wir ... verwenden

package main

import (
    "fmt"
)

func main() {
    x := []int{1, 2, 3}
    y := []int{4, 5, 6}
    z := append([]int{}, append(x, y...)...)
    fmt.Println(z)
}

ausgabe des obigen Codes ist: [1 2 3 4 5 6]

3
ASHWIN RAJEEV

append([]int{1,2}, []int{3,4}...) wird funktionieren. Argumente an ...-Parameter übergeben.

Wenn f mit einem Endparameter p vom Typ ...T variadisch ist, entspricht der Typ von f innerhalb von p dem Typ []T

Wenn f ohne tatsächliche Argumente für p aufgerufen wird, ist der an p übergebene Wert nil

Andernfalls ist der übergebene Wert ein neues Slice vom Typ []T mit einem neuen zugrunde liegenden Array, dessen aufeinanderfolgende Elemente die eigentlichen Argumente sind, die alle T zugewiesen werden können. Die Länge und Kapazität des Slice ist daher die Anzahl der an p gebundenen Argumente und kann für jede Aufrufstelle unterschiedlich sein.

Angesichts der Funktion und der Anrufe

func Greeting(prefix string, who ...string)
Greeting("nobody")
Greeting("hello:", "Joe", "Anna", "Eileen")
0
BaSO4