I want delete some elements from a slice, and https://github.com/golang/go/wiki/SliceTricks advise this slice-manipulation:

a = append(a[:i], a[i+1:]...)

Then I coded below:

package main

import (
    "fmt"
)

func main() {
    slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    for i, value := range slice {
        if value%3 == 0 { // remove 3, 6, 9
            slice = append(slice[:i], slice[i+1:]...)
        }
    }
    fmt.Printf("%v
", slice)
}
go run hello.go
panic: runtime error: slice bounds out of range

goroutine 1 [running]:
panic(0x4ef680, 0xc082002040)
    D:/Go/src/runtime/panic.go:464 +0x3f4
main.main()
    E:/Code/go/test/slice.go:11 +0x395
exit status 2

How can I change this code to get right?

I tried below:

goto
func main() {
    slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
Label:
    for i, n := range slice {
        if n%3 == 0 {
            slice = append(slice[:i], slice[i+1:]...)
            goto Label
        }
    }
    fmt.Printf("%v
", slice)
}

it works, but too much iteration

2nd, use another slice sharing same backing array:

func main() {
    slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    dest := slice[:0] 
    for _, n := range slice {
        if n%3 != 0 { // filter
            dest = append(dest, n)
        }
    }
    slice = dest
    fmt.Printf("%v
", slice)
}

but not sure if this one is better or not.

len
func main() {
    slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    for i := 0; i < len(slice); i++ {
        if slice[i]%3 == 0 {
            slice = append(slice[:i], slice[i+1:]...)
            i-- // should I decrease index here?
        }
    }
    fmt.Printf("%v
", slice)
}

which one should I take now?

with benchmark:

func BenchmarkRemoveSliceElementsBySlice(b *testing.B) {
    for i := 0; i < b.N; i++ {
        slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
        dest := slice[:0]
        for _, n := range slice {
            if n%3 != 0 {
                dest = append(dest, n)
            }
        }
    }
}

func BenchmarkRemoveSliceElementByLen(b *testing.B) {
    for i := 0; i < b.N; i++ {
        slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
        for i := 0; i < len(slice); i++ {
            if slice[i]%3 == 0 {
                slice = append(slice[:i], slice[i+1:]...)
            }
        }
    }
}


$ go test -v -bench=".*"
testing: warning: no tests to run
PASS
BenchmarkRemoveSliceElementsBySlice-4   50000000                26.6 ns/op
BenchmarkRemoveSliceElementByLen-4      50000000                32.0 ns/op

it seems delete all elements in one loop is better