fmt.Println("Enter position to delete::")
fmt.Scanln(&pos)

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++
        i++
    } else {
        k++
    }
}

for i := 0; i < (len(arr) - 1); i++ {
    fmt.Println(new_arr[i])
}

我正在使用这个命令从切片中删除一个元素,但它不起作用,请建议。


当前回答

在语言教程中,我们了解到:

片类似于数组的引用。 片不存储任何数据,它只是描述底层数组的一部分。 改变片的元素将修改其底层数组的相应元素。

出于这个原因,在片上使用附加函数而不考虑我们正在处理的值的起源和目的地是非常危险的,也是错误的。

因此,正确的解决方案是使用引用到新数组而不是“主”数组的片。 这可以通过make构造创建一个新切片来实现。

func removeAt(slice []int, index int) []int {
    newSlice := make([]int, 0) //Create a new slice of type []int and length 0
    newSlice = append(newSlice, slice[:index]...) //Copies the values contained in the old slice to the new slice up to the index (excluded)
    if index != len(slice)-1 {
        newSlice = append(newSlice, slice[index+1:]...) //If the index to be removed was different from the last one, then proceed to copy the following values of the index to the end of the old slice
    }
    return newSlice
}

通过这种方式,我们能够安全地删除片中的元素,而不管我们将在函数返回时使用什么。


由于我使用了一个函数来回答这个问题,它将是一个好主意处理任何错误如下:

func removeAt(slice []int, index int) ([]int, error) {
    if index < 0 {
        return nil, fmt.Errorf("index (%d) cannot be a negative number", index)
    }
    if index >= len(slice) {
        return nil, fmt.Errorf("index (%d) cannot be a number greater or equal than the length of slice (%d)", index, len(slice))
    }

    newSlice := make([]int, 0)
    newSlice = append(newSlice, slice[:index]...)
    if index != len(slice)-1 {
        newSlice = append(newSlice, slice[index+1:]...)
    }
    
    return newSlice, nil
}

或者更好的是,实现可以通过接口处理多种类型的函数。 但是,所有这些都是一种很好的实践,因为您构建了一个函数来执行此操作,这与所提出的问题无关。

但是,在这里可以找到一个在围棋操场上测试的例子。

其他回答

从切片中移除一个元素(这称为“重新切片”):

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) //[0 1 2 3 4 5 6 7 8 9]
    all = RemoveIndex(all, 5)
    fmt.Println(all) //[0 1 2 3 4 6 7 8 9]
}

下面是带有指针的操场示例。 https://play.golang.org/p/uNpTKeCt0sH

package main

import (
    "fmt"
)

type t struct {
    a int
    b string
}

func (tt *t) String() string{
    return fmt.Sprintf("[%d %s]", tt.a, tt.b)
}

func remove(slice []*t, i int) []*t {
  copy(slice[i:], slice[i+1:])
  return slice[:len(slice)-1]
}

func main() {
    a := []*t{&t{1, "a"}, &t{2, "b"}, &t{3, "c"}, &t{4, "d"}, &t{5, "e"}, &t{6, "f"}}
    k := a[3]
    a = remove(a, 3)
    fmt.Printf("%v  ||  %v", a, k)
}

T. Claverie目前投票最多的答案是正确的,但我发现如果只在需要时执行交换,即对片的最后一个元素以外的所有元素执行交换,算法会更清晰。这可以通过一个简单的if守卫来实现。

秩序不重要/没有进行边界检查

func remove(s []int, i int) []int {
    // bring element to remove at the end if its not there yet
    if i != len(s)-1 {
        s[i] = s[len(s)-1]
    }
 
    // drop the last element
    return s[:len(s)-1]
}

在语言教程中,我们了解到:

片类似于数组的引用。 片不存储任何数据,它只是描述底层数组的一部分。 改变片的元素将修改其底层数组的相应元素。

出于这个原因,在片上使用附加函数而不考虑我们正在处理的值的起源和目的地是非常危险的,也是错误的。

因此,正确的解决方案是使用引用到新数组而不是“主”数组的片。 这可以通过make构造创建一个新切片来实现。

func removeAt(slice []int, index int) []int {
    newSlice := make([]int, 0) //Create a new slice of type []int and length 0
    newSlice = append(newSlice, slice[:index]...) //Copies the values contained in the old slice to the new slice up to the index (excluded)
    if index != len(slice)-1 {
        newSlice = append(newSlice, slice[index+1:]...) //If the index to be removed was different from the last one, then proceed to copy the following values of the index to the end of the old slice
    }
    return newSlice
}

通过这种方式,我们能够安全地删除片中的元素,而不管我们将在函数返回时使用什么。


由于我使用了一个函数来回答这个问题,它将是一个好主意处理任何错误如下:

func removeAt(slice []int, index int) ([]int, error) {
    if index < 0 {
        return nil, fmt.Errorf("index (%d) cannot be a negative number", index)
    }
    if index >= len(slice) {
        return nil, fmt.Errorf("index (%d) cannot be a number greater or equal than the length of slice (%d)", index, len(slice))
    }

    newSlice := make([]int, 0)
    newSlice = append(newSlice, slice[:index]...)
    if index != len(slice)-1 {
        newSlice = append(newSlice, slice[index+1:]...)
    }
    
    return newSlice, nil
}

或者更好的是,实现可以通过接口处理多种类型的函数。 但是,所有这些都是一种很好的实践,因为您构建了一个函数来执行此操作,这与所提出的问题无关。

但是,在这里可以找到一个在围棋操场上测试的例子。

最好的方法是使用append函数:

package main

import (
    "fmt"
)

func main() {
    x := []int{4, 5, 6, 7, 88}
    fmt.Println(x)
    x = append(x[:2], x[4:]...)//deletes 6 and 7
    fmt.Println(x)
}

https://play.golang.org/p/-EEFCsqse4u