To trochę dziwne, ale większość odpowiedzi tutaj jest niebezpieczna i przesłania to, co faktycznie robią. Patrząc na pierwotne pytanie, które zostało zadane na temat usuwania elementu z plasterka, kopia plastra jest tworzona, a następnie jest wypełniana. Gwarantuje to, że gdy plasterki są przekazywane wokół programu, nie wprowadzasz subtelnych błędów.
Oto kod porównujący odpowiedzi użytkowników w tym wątku i oryginalny post. Oto plac zabaw, w którym można bawić się tym kodem.
Usuwanie na podstawie dołączania
package main
import (
"fmt"
)
func RemoveIndex(s []int, index int) []int {
return append(s[:index], s[index+1:]...)
}
func main() {
all := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
fmt.Println("all: ", all)
removeIndex := RemoveIndex(all, 5)
fmt.Println("all: ", all)
fmt.Println("removeIndex: ", removeIndex)
removeIndex[0] = 999
fmt.Println("all: ", all)
fmt.Println("removeIndex: ", removeIndex)
}
W powyższym przykładzie możesz zobaczyć, jak tworzę wycinek i ręcznie wypełniam go numerami od 0 do 9. Następnie usuwamy indeks 5 ze wszystkich i przypisujemy go do usunięcia indeksu. Jednak kiedy idziemy teraz wydrukować wszystko, widzimy, że zostało to również zmodyfikowane. Dzieje się tak, ponieważ plasterki są wskaźnikami do tablicy bazowej. Zapisanie go do removeIndex
przyczyn, które all
mają być również zmodyfikowane, z tą różnicą, że all
jest dłuższy o jeden element, z którego nie można już dotrzeć removeIndex
. Następnie zmieniamy wartość w removeIndex
i widzimy, że również all
zostaje zmodyfikowana. Efektywne przejście do bardziej szczegółowych informacji na ten temat.
Poniższy przykład, którym nie będę się zajmował, ale robi to samo dla naszych celów. I tylko pokazuje, że używanie kopiowania nie jest inne.
package main
import (
"fmt"
)
func RemoveCopy(slice []int, i int) []int {
copy(slice[i:], slice[i+1:])
return slice[:len(slice)-1]
}
func main() {
all := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
fmt.Println("all: ", all)
removeCopy := RemoveCopy(all, 5)
fmt.Println("all: ", all)
fmt.Println("removeCopy: ", removeCopy)
removeCopy[0] = 999
fmt.Println("all: ", all)
fmt.Println("removeCopy: ", removeCopy)
}
Na pytania oryginalna odpowiedź
Patrząc na oryginalne pytanie, nie modyfikuje plastra, z którego usuwa element. Jak dotąd oryginalna odpowiedź w tym wątku była jak dotąd najlepsza dla większości osób odwiedzających tę stronę.
package main
import (
"fmt"
)
func OriginalRemoveIndex(arr []int, pos int) []int {
new_arr := make([]int, (len(arr) - 1))
k := 0
for i := 0; i < (len(arr) - 1); {
if i != pos {
new_arr[i] = arr[k]
k++
} else {
k++
}
i++
}
return new_arr
}
func main() {
all := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
fmt.Println("all: ", all)
originalRemove := OriginalRemoveIndex(all, 5)
fmt.Println("all: ", all)
fmt.Println("originalRemove: ", originalRemove)
originalRemove[0] = 999
fmt.Println("all: ", all)
fmt.Println("originalRemove: ", originalRemove)
}
Jak widać, ten wynik działa zgodnie z oczekiwaniami większości ludzi i prawdopodobnie tym, czego większość ludzi chce. Modyfikacja originalRemove
nie powoduje zmian, all
a operacja usunięcia indeksu i przypisanie go również nie powoduje zmian! Fantastyczny!
Ten kod jest jednak trochę za długi, więc powyższy można zmienić na ten.
Prawidłowa odpowiedź
package main
import (
"fmt"
)
func RemoveIndex(s []int, index int) []int {
ret := make([]int, 0)
ret = append(ret, s[:index]...)
return append(ret, s[index+1:]...)
}
func main() {
all := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
fmt.Println("all: ", all)
removeIndex := RemoveIndex(all, 5)
fmt.Println("all: ", all)
fmt.Println("removeIndex: ", removeIndex)
removeIndex[0] = 999
fmt.Println("all: ", all)
fmt.Println("removeIndex: ", removeIndex)
}
Prawie identyczne z oryginalnym rozwiązaniem do usuwania indeksu, jednak przed powrotem tworzymy nowy wycinek do dołączenia.