func main() {
a := []string{"Hello1", "Hello2", "Hello3"}
fmt.Println(a)
// [Hello1 Hello2 Hello3]
a = append(a[:0], a[1:]...)
fmt.Println(a)
// [Hello2 Hello3]
}
这个使用append函数的删除技巧是如何工作的?
看起来它在抓取第一个元素(空数组)之前的所有内容
然后在第一个元素(位置零)后追加所有内容
这是什么...(点点点点)做什么?
8条答案
按热度按时间r1zhe5dt1#
其中
a
是切片,i
是要删除的元素的索引:...
是Go语言中可变参数的语法。基本上,当定义一个函数时,它会把你传递的所有参数放入该类型的一个切片中。通过这样做,您可以传递任意多个参数(例如,
fmt.Println
可以接受任意多个参数)。现在,当调用一个函数时,
...
会做相反的事情:它解包切片并将它们作为单独的参数传递给可变参数函数。这行代码的作用是:
本质上是:
现在,你可能想知道,为什么不直接做
append
的函数定义是所以第一个参数必须是正确类型的切片,第二个参数是可变参数,所以我们传入一个空切片,然后解包切片的其余部分以填充参数。
gijlo24d2#
有两种选择:
A:您关心的是保持数组顺序:
B:你不关心保持秩序(这可能更快):
如果你的数组是指针的话,请看链接来了解内存泄漏的含义。
https://github.com/golang/go/wiki/SliceTricks
von4xj4u3#
与其将
[a:]
-、[:b]
-和[a:b]
-表示法中的索引视为元素索引,不如将它们视为元素周围和元素之间的间隙的索引,从索引为0
的元素之前索引为0
的间隙开始。只看蓝色的数字,就更容易看出发生了什么:
[0:3]
包含所有内容,[3:3]
是空的,[1:2]
将产生{"B"}
。那么[a:]
只是[a:len(arrayOrSlice)]
的短版本,[:b]
是[0:b]
的短版本,[:]
是[0:len(arrayOrSlice)]
的短版本。后者通常用于在需要时将数组转换为切片。qyuhtwio4#
...是可变参数的语法。
我认为它是由编译器使用slice(
[]Type)
实现的,就像函数append:当你在“append”中使用“elems”时,实际上它是一个切片([]类型)。所以“
a = append(a[:0], a[1:]...)
“的意思是“a = append(a[0:0], a[1:])
“a[0:0]
是一个什么都没有的切片a[1:]
是“Hello2 Hello3”这就是它的工作原理
js4nwp545#
我得到了一个索引超出范围的错误与接受的答案解决方案。原因:当范围开始时,它不是逐个迭代值,而是按索引迭代。如果在范围内修改切片,则会导致一些问题。
老答案:
预期:
实际:
正确方法(解决方案):
来源:https://dinolai.com/notes/golang/golang-delete-slice-item-in-range-problem.html
xj3cbfub6#
假设你的slice的值是这样的:
[9 3 7 11 4 12 16 19 4]
删除7和11元素
x = append(x[:2], x[4:]...)
现在的结果是:
[9 4 12 16 19 4]
希望有帮助!
jdg4fx2g7#
创建两个没有删除值的切片并将它们连接起来
3qpi33ja8#
不是一个优雅的方法,但它的工作。(使用
strings.Replace
)