Bei jedem Anhängevorgang wird überprüft, ob das Slice über genügend Kapazität verfügt. Wenn diese ausreicht, werden Elemente direkt an das ursprüngliche Array angehängt und ein neues Slice zurückgegeben. Das zugrunde liegende Array bleibt unverändert. Wenn die Kapazität nicht ausreicht, wird ein neues zugrunde liegendes Array mit ausreichender Kapazität erstellt. Kopieren Sie zunächst die Elemente des vorherigen Arrays, hängen Sie die neuen Elemente an die Rückseite an und geben Sie dann das neue zurück Das zugrunde liegende Array ändert sich und die Kapazitätsdefinition des neuen Arrays lautet wie folgt Heute habe ich bei Reflect.SliceHeader festgestellt, dass die Erweiterung von append nicht gerade eine Verdoppelung darstellt. Der Quellcode lautet wie folgt (Go-Version 1.13):
// grow grows the slice s so that it can hold extra more values, allocating
// more capacity if needed. It also returns the old and new slice lengths.
func grow(s Value, extra int) (Value, int, int) {
i0 := s.Len()
i1 := i0 + extra
if i1 < i0 {
panic("reflect.Append: slice overflow")
}
m := s.Cap()
if i1 <= m {
return s.Slice(0, i1), i0, i1
}
if m == 0 {
m = extra
} else {
for m < i1 {
if i0 < 1024 {
m += m
} else {
m += m / 4
}
}
}
t := MakeSlice(s.Type(), i1, m)
Copy(t, s)
return t, i0, i1
}
// Append appends the values x to a slice s and returns the resulting slice.
// As in Go, each x's value must be assignable to the slice's element type.
func Append(s Value, x ...Value) Value {
s.mustBe(Slice)
s, i0, i1 := grow(s, len(x))
for i, j := i0, 0; i < i1; i, j = i+1, j+1 {
s.Index(i).Set(x[j])
}
return s
}
Nach dem Login kopieren
Zuerst bestimmt Append, ob der Typ Slice ist, und dann Aus der Beurteilung von l1 <= m lässt sich schließen, dass bei ausreichender Kapazität lediglich ein neues Slice für das ursprüngliche Array erstellt wird. Wenn die Kapazität jedoch nicht ausreicht, ist dies möglich Beachten Sie, dass die 2-fache Geschwindigkeit nur dann normal ist, wenn das aktuelle Element i0 kleiner als 1024 ist. Andernfalls erfolgt die Codeüberprüfung wie folgt: 乘以2
Das obige ist der detaillierte Inhalt vonÜber die Append-Erweiterung von Golang Slice. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn