为什么我的append函数将切片的每个成员更改为要添加的新项目?

时间:2019-03-04 17:41:51

标签: go

我正在制作一个简单的素因函数,可以放置像[][]int这样的切片

prime_factors_mult(315) => [[3,2],[5,1],[7,1]]

但是我得到[[7,1][7,1][7,1][7,1]]而不是这个结果,由于它们重复了自己,所以后来减少为空切片。我试图逐步查看它,并将所有值更改为最后一个附录。我应该怎么做才能避免这种情况?

func prime_factors_mult(x []int)(y [][]int){// Problem 36
    in :=[]int{0,0}
    var k [][]int
    for _,item := range x{
        tok := 0
        for i:=0;i<len(x);i++{
            if item == x[i]{
                tok++
            }
        }
        in[0]=item
        in[1]=tok
        k=append(k,in)
    }
    for _,item := range k{
        for i:=0;i<len(k);i++{
            if item[0] != k[i][0]{
                y = append(y,item)
            }
        }
    }
    return
}

2 个答案:

答案 0 :(得分:2)

您一次创建in切片,然后每次对其进行修改,因此每次都将完全相同的对象添加到k

改为附加一个 new 切片:

k=append(k,[]int{item, tok})

答案 1 :(得分:0)

Range的语法每次都会返回索引和该值的引用。您选择两次都使用引用,并且值被修改,但您仍要追加相同的地址。这就是为什么您只获得最后一个值,范围循环不断对其进行修改,而您只剩下循环中的最后一个值的原因。

方法1:

为避免这种情况,请将循环更改为for index := range k而不是for _,item := range k,请使用循环中的索引并附加k[index]而不是item。

方法2:

for _, item range something {
  item := item

如果您希望保持语法不变,则可以使用从范围获得的变量在循环内创建局部变量。在两个循环块的第一行中添加item := item。尽管看起来很奇怪,但这每次都会分配新的item,您将附加并使用 that 变量。