通过附加到golang中的现有切片来创建新切片

问题描述

我正在编写一个程序,以生成一片唯一元素的所有可能排列。 相同的代码可以在here

中找到

有一次我需要从原始数字切片中创建一个新切片。这个新切片的元素比原始切片少一个。我用append

尝试了两种不同的变体

nums是原始切片,而remaining是我尝试创建的新切片。 iint,范围从0len(nums)-1

变种1:

remaining := make([]int,0)
remaining = append(remaining,nums[:i]...)
remaining = append(remaining,nums[i+1:]...)

变种2:

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

虽然程序在Variant 1上可以正常运行,但在Variant 2上无法正常运行。 我想了解这两个变体的确切区别是什么?

解决方法

此处切片nums[:i]是通过切片更大的数组nums来创建的。这导致它具有足够的容量来扩展就位。因此,类似append(nums[:i],nums[i+1:]...)的操作会导致nums中的元素被nums[i+1:]中的元素覆盖。这会改变原始数组,从而改变其行为。

如@icza所建议,该概念已被捕获here

要修复版本2,我们可以像这样使用full slice expression

remaining := append(nums[0:i:i],nums[i+1:len(nums):len(nums)]...)