为了账号安全,请及时绑定邮箱和手机立即绑定

删除切片中的每个元素

删除切片中的每个元素

Go
红糖糍粑 2021-09-27 14:13:08
当我尝试使用SliceTricks 中建议的Delete方法遍历切片并按顺序删除每个元素以打印剩余元素时,出现了一些意外行为。例如,当我尝试遍历包含字母的切片时[A B C],我希望输出为[B C], [A C],[A B]按以下顺序:方法一package mainimport "fmt"func main() {    a := []string {"A", "B", "C"}    for i, _ := range a {        fmt.Println(append(a[:i], a[i+1:]...))    }}然而,这里的输出让我感到惊讶。它输出[B C]三倍。通过执行以下操作,我最终确实得到了预期的行为:方法二package mainimport "fmt"func main() {    a := []string {"A", "B", "C"}    for i, _ := range a {        result := make([]string, 0)        result = append(result, a[:i]...)        result = append(result, a[i+1:]...)        fmt.Println(result)    }}是什么导致了方法 1 中的意外行为,除了方法 2 之外,还有没有更好的方法来实现这一点?
查看完整描述

3 回答

?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

“什么”是因为append(slice, elems...)实际上是slice用新元素更新。它仅返回一个“新”切片,因为它可能由于内存重新分配而不得不重新定位原始切片。因此,在您的示例代码中,您实际上是a在每次调用append. (此golang 博客文章的“附加:示例”部分中有一个很好的概述)。


至于“如何”,我的尝试是:


package main


import "fmt"


func main() {

    a := []string {"A", "B", "C"}

    for i, _ := range a {

        result := make([]string, i, len(a)-1)

        copy(result, a[:i])

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

        fmt.Println(result)

    }

}


使用result长度和容量进行初始化,以及使用copy而不是两个appends 尝试减少所需的内存重新分配次数。


查看完整回答
反对 回复 2021-09-27
  • 3 回答
  • 0 关注
  • 168 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信