func main() {
a := []string{"Hello1", "Hello2", "Hello3"}
fmt.Println(a)
// [Hello1 Hello2 Hello3]
a = append(a[:0], a[1:]...)
fmt.Println(a)
// [Hello2 Hello3]
}
Jak działa ta sztuczka usuwania z funkcją dołączania?
Wydawałoby się, że przechwytuje wszystko przed pierwszym elementem (pusta tablica)
Następnie dołączanie wszystkiego po pierwszym elemencie (pozycja zero)
Co robi ... (kropka kropka kropka)?
...
jest tam szczegółowo wyjaśnione?Odpowiedzi:
Gdzie
a
jest wycinek, ai
jest indeksem elementu, który chcesz usunąć:...
to składnia argumentów wariadycznych w Go.Zasadniczo podczas definiowania funkcji umieszcza wszystkie przekazywane argumenty w jednym wycinku tego typu. W ten sposób możesz przekazać dowolną liczbę argumentów (na przykład
fmt.Println
możesz przyjąć dowolną liczbę argumentów).Teraz, wywołując funkcję,
...
robi odwrotnie: rozpakowuje plasterek i przekazuje je jako oddzielne argumenty do funkcji wariadycznej.Więc co robi ta linia:
to zasadniczo:
Teraz możesz się zastanawiać, dlaczego po prostu tego nie zrobić
Cóż, definicja funkcji
append
toWięc pierwszy argument musi być kawałkiem odpowiedniego typu, drugi argumentem jest wariadą, więc przekazujemy pusty wycinek, a następnie rozpakowujemy resztę wycinka, aby wypełnić argumenty.
źródło
a = append(a[:i], a[i+1:]...)
Istnieją dwie możliwości:
O: Zależy Ci na zachowaniu kolejności tablic:
B: Nie zależy Ci na zachowaniu kolejności (prawdopodobnie jest to szybsze):
Zobacz link, aby zobaczyć konsekwencje wycieków pamięci, jeśli twoja tablica zawiera wskaźniki.
https://github.com/golang/go/wiki/SliceTricks
źródło
Zamiast myśleć o indeksach w adnotacjach
[a:]
-,[:b]
- i -[a:b]
jako o indeksach elementów, myśl o nich jako o indeksach luk wokół i między elementami, zaczynając od przerwy indeksowanej0
przed elementem indeksowanym jako0
.Patrząc tylko na niebieskie liczby, znacznie łatwiej jest zobaczyć, co się dzieje:
[0:3]
obejmuje wszystko,[3:3]
jest puste i[1:2]
ustąpi{"B"}
. Następnie[a:]
jest tylko skrócona wersja[a:len(arrayOrSlice)]
,[:b]
skrócona wersja[0:b]
i[:]
skrócona wersja[0:len(arrayOrSlice)]
. Ten ostatni jest powszechnie używany do przekształcania tablicy w plasterek, gdy jest to potrzebne.źródło
... jest składnią argumentów wielorakich.
Myślę, że jest to implementowane przez osobę odpowiedzialną za pomocą plastra (
[]Type)
podobnie jak funkcja append:kiedy używasz "elems" w "append", w rzeczywistości jest to kawałek (typ []). Więc „
a = append(a[:0], a[1:]...)
” oznacza „a = append(a[0:0], a[1:])
”a[0:0]
to kawałek, który nie ma nica[1:]
to „Hello2 Hello3”Tak to działa
źródło
a[0:0]
to nienil
tylko kawałek o zerowej długości.a[0:0]
będzie tylko byćnil
, jeślia
jestnil
.Otrzymuję indeks poza zakresem z zaakceptowanym rozwiązaniem odpowiedzi. Powód: kiedy zaczyna się zakres, nie jest to iteracja wartości jeden po drugim, lecz iteracja według indeksu. Jeśli zmodyfikowałeś kawałek, gdy był w zasięgu, spowoduje to pewien problem.
Stara odpowiedź:
Spodziewany :
Rzeczywisty:
Właściwy sposób (rozwiązanie):
Źródło: https://dinolai.com/notes/golang/golang-delete-slice-item-in-range-problem.html
źródło
Na wiki golanga pokazuje kilka sztuczek do plasterka, w tym usuwanie elementu z plasterka.
Link: wprowadź opis linku tutaj
Na przykład a jest wycinkiem, z którego chcesz usunąć element numer i.
LUB
źródło