【发布时间】:2020-08-02 05:15:11
【问题描述】:
我对 Go 语言有点陌生,并试图构建一个函数,它将一个切片细分为多个大小几乎相等的切片。如果主切片的大小不适合子切片的数量,我打算将剩余的元素按顺序重新分配到子切片。
我已经构建了以下代码:
package main
import (
"fmt"
stc "strconv"
"strings"
)
func main() {
myslice := make([]int, 12)
myslice = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
fmt.Println("Original Slice = ", myslice)
newdiv := subslices(myslice, 4)
fmt.Println(newdiv)
}
func subslices(sl []int, dividnet int) [][]int {
var res [][]int
minsize := len(sl) / dividnet
for i := 0; i < dividnet; i++ {
res = append(res, sl[i*minsize:i*minsize+minsize])
}
for i := 0; i < dividnet; i++ {
fmt.Printf("res[%d] = %v\n", i, res[i])
}
fmt.Println(res)
if rem := len(sl) % dividnet; rem != 0 {
fmt.Println("remaining elements = ", rem)
for j := 0; j < rem; j++ {
tobeadd := sl[minsize*dividnet+j]
fmt.Println("element to be added = ", tobeadd)
fmt.Printf("res[%d] before append = %v\n", j, res[j])
res[j] = append(res[j], tobeadd)
fmt.Printf("res[%d] after append = %v\n", j, res[j])
}
}
return res
}
func gentwodim(x, y int) [][]int {
res := make([][]int, x)
for z := range res {
res[z] = make([]int, y)
}
for i := 0; i < x; i++ {
for j := 0; j < y; j++ {
res[i][j] = i + j
}
}
return res
}
Go Play 示例 sample of the above code
代码输出如下:
res[0] = [1 2]
res[1] = [3 4]
res[2] = [5 6]
res[3] = [7 8]
[[1 2] [3 4] [5 6] [7 8]]
remaining elements = 2
element to be added = 9
res[0] before append = [1 2]
res[0] after append = [1 2 9] // up to this step the code works fine
element to be added = 10
res[1] before append = [9 4] // I did not get why res[1] is changed by replacing 3 with 9
res[1] after append = [9 4 10]
[[1 2 9] [9 4 10] [10 6] [7 8]]
但是,在添加了res[0] after append = [1 2 9] 中显示的第一个剩余元素后,第二个子切片从res[1] = [3 4] 更改为res[1] before append = [9 4]
我试图调试并理解我在这里遗漏或编码错误的内容,但不能。
感谢您的支持。
【问题讨论】:
-
这是因为切片有一个底层数组,如果将 myslice 切片成 4 个子切片,所有这些切片仍然具有相同的底层数组,它们只是“查看”数组的不同段。如果底层数组中有足够的空间,附加到这些子切片之一将更新底层数组中的元素。这里有效地流血到下一个子切片。
-
...见这里play.golang.org/p/L0GyulibYB6,在附加到结果之前会创建一个子切片的副本,这样每个子切片都有自己的底层数组。
-
如果你对细节感兴趣可以去这里:blog.golang.org/slices-intro
-
@mkopriva,非常感谢,您解决了这个问题。感谢您为纠正代码所做的努力。