Ich bin verwirrt darüber, wie der folgende Code funktioniert, vor allem, was der Zweck ist "..."Was macht die folgende Go-Array-Operation?
array = append(array[:i], array[i+1:]...)
Ich bin verwirrt darüber, wie der folgende Code funktioniert, vor allem, was der Zweck ist "..."Was macht die folgende Go-Array-Operation?
array = append(array[:i], array[i+1:]...)
Die Linie
a = append(a[:i], a[i+1:]...)
erstellt eine neue Scheibe durch das Element in Position zu entfernen i
in a
, indem sie die Elemente von 0 bis i Kombinieren (nicht enthalten) und von i + 1 bis zum Ende.
Ihre zweite Frage ist, was der Zweck von ...
ist. append
akzeptiert eine Scheibe als erstes Argument und eine unbegrenzte Anzahl von Argumenten, alle mit einem Typ assignable an den Typ seiner Elemente.
append
definiert als
func append(slice []Type, elems ...Type) []Type
Schreiben
a = append(a[:i], a[i+1:]...)
ist gleichwertig wie das Schreiben
a = append(a[:i], a[i+1], a[i+2], a[i+3], a[i+4]) //and so on, until the end of the slice.
Verwendung a[i+1:]...
ist im Grunde eine Kurzschrift-Syntax, wie die Go spec in https://golang.org/ref/spec#Passing_arguments_to_..._parameters beschreibt:
Wenn f mit einem letzten Parameter p vom Typ ... T variabel ist, dann entspricht der Typ von p innerhalb von f dem Typ [] T. Wenn f ohne tatsächliche Argumente für p aufgerufen wird, ist der an p übergebene Wert nil. Andernfalls übergebene Wert ist ein neues Stück des Typs [] T mit einem neuen darunterliegenden Array, dessen aufeinanderfolgende Elemente sind die aktuellen Argumente, die alle zuweisbaren sein muss
Built-in func append ist Variadische Funktion.
Um slice Argument zu jeder variadische Funktion übergeben, haben Sie ...
Go lang spec verwenden: Passing arguments to ... parameters
Wenn f mit der endgültigen Parameter-Typ ... T, dann innerhalb der variadische ist Funktion Das Argument entspricht einem Parameter vom Typ [] T. Bei jeder Aufruf von f, das Argument an den letzten Parameter übergeben ist eine neue Scheibe des Typs [] T, deren aufeinanderfolgende Elemente sind die tatsächlichen Argumente, , die alle dem Typ T zugeordnet werden können. Die Länge der Scheibe ist daher die Anzahl der Argumente an den letzten Parameter gebunden und kann für jede Call-Site unterscheiden.
Diese Linie würden Sie Position zu entfernen einen Ergebniswert geben i
.
array = append(array[:i], array[i+1:]...)
Lassen Sie uns sagen, wir haben
array := []int{1, 2, 3, 4, 5, 6, 7}
i := 3
fmt.Println("Original slice:", array)
part1 := array[:i]
part2 := array[i+1:]
fmt.Println("part1:", part1)
fmt.Println("part2:", part2)
array = append(array[:i], array[i+1:]...)
fmt.Println("Result slice:", array)
Ausgang:
Original slice: [1 2 3 4 5 6 7]
part1: [1 2 3]
part2: [5 6 7]
Result slice: [1 2 3 5 6 7]
Wiedergabe-Link: https://play.golang.org/p/_cIk0VcD6w
Der Zweck ...
ist, dass Sie einzelne Elemente als append
Eingabe zu speichern Methode nimmt erstes Argument als sl ice und dann variable Anzahl von Argumenten für anzuhängende Elemente.
dh Sie eigentlich anrufen müssen anhängen als
append(sliceName[:i], array[i+1], array[i+2], array[i+3], array[i+4])
aber lange Liste von Elementen der Eingabe zu vermeiden, können Sie einfach ...
nach der Scheibe oder Array verwenden können sie als einzelne Elemente zu verbreiten als übergeben werden Argumente.
array = append(array[:i], array[i+1:]...)
Entfernen T Ein Element bei Index i
aber eine andere Sache, darauf hinzuweisen, ist, dass Slice von einem zugrunde liegenden Array unterstützt wird. Zum Beispiel:
package main
import (
"fmt"
)
func main() {
myArray := [6]int {1,2,3,4,5,6}
mySlice := myArray[:]
fmt.Println("myArray before append: ", myArray)
i := 3
mySlice = append(mySlice[:i], mySlice[i+1:]...)
fmt.Println("mySlice after append: ", mySlice)
fmt.Println("myArray after append: ", myArray)
}
Ergebnis:
myArray before append: [1 2 3 4 5 6]
mySlice after append: [1 2 3 5 6]
myArray after append: [1 2 3 5 6 6]
Im zugrunde liegenden [1,2,3]
an Ort und Stelle geblieben, dass Daten nie irgendwo bewegt gehen, während [5,6]
die von b[i+1]
gegeben wurden [1,2,3]
angehängt wurden und überschrieb so [3,4]
; die anderen [6]
blieben an Ort und Stelle.
Auch wenn Sie eine andere Kopie eines Slices erhalten, ist das zugrundeliegende Array das gleiche *, dies macht das Anhängen zu einem viel effizienteren Vorgang, wenn das gesamte darunterliegende Array kopiert werden muss!
* Wenn das zugrundeliegende Array seine Kapazität überschreitet, wird ein neues größeres Array zugewiesen, und die Werte des alten Arrays werden in das neue Array kopiert. Dies geschieht jedoch niemals beim Entfernen eines Elements.
Also macht diese Linie einen neuen Slice, indem sie die Elemente 0 bis i-1 mit Elementen verbindet, die mit i + 1 beginnen und bis zum Ende des Slices fortfahren. Mit anderen Worten, der Effekt besteht darin, das Element "i" aus "array" zu löschen (indem ein neues Slice erstellt wird; dies geschieht nicht an Ort und Stelle). –