gpt4 book ai didi

go - 将值附加到 slice 时,值与原始值不同

转载 作者:数据小太阳 更新时间:2023-10-29 03:36:52 25 4
gpt4 key购买 nike

考虑这段代码:

package main

import (
"fmt"
)

func main() {
fmt.Println(Part(11))
}

func Part(n int) string {
enumResult := [][]int{}
enum(n, n, []int{}, &enumResult)
fmt.Println(enumResult)
fmt.Println(40, enumResult[40])
return ""
}

var abc int = 0

func enum(n int, top int, pre []int, result *[][]int) {
var i int
if n > top {
i = top
} else {
i = n
}
for ; i > 0; i-- {
tempResult := append(pre, i)
if n-i == 0 {
/* if tempResult[0] == 3 && tempResult[1] == 3 && tempResult[2] == 3 && tempResult[3] == 2 {
tempResult = append(tempResult, 12345)
}*/
fmt.Println(abc, tempResult)
abc++
*result = append(*result, tempResult)
} else {
enum(n-i, i, tempResult, result)
}
}
}

当我运行这段代码时

我将值“[3,3,3,2]”附加到“enumResult”

但是如果我检查 'enumResult' 的值,则会出现 '[3,3,3,1]'

它的索引是 40 =>enumResult[40](其他值正确)

我不知道为什么会这样你能给我解释一下为什么吗?

最佳答案

确实是append的问题。

关于append有两件事。首先,append 不一定复制内存。作为spec指定:

If the capacity of s is not large enough to fit the additional values, append allocates a new, sufficiently large underlying array that fits both the existing slice elements and the additional values. Otherwise, append re-uses the underlying array.

如果您不清楚,这可能会导致意外行为。 Playground 示例:https://play.golang.org/p/7A3JR-5IX8o

第二部分是,当append 复制内存时,它会增加 slice 的容量。然而,它不会只增加 1。 Playground 示例:https://play.golang.org/p/STr9jMqORUz

slice 增长多少 append 是未记录的,被认为是实现细节。但是直到 Go 1.10,它遵循这个规则:

Go slices grow by doubling until size 1024, after which they grow by 25% each time.

请注意,启用竞争检测器时,这可能会改变。增长 slice 的代码位于$GOROOT/src/runtime/slice.go中的growslice函数。

现在回到问题。现在应该很清楚,由于之前 append 的 slice 增长,您的代码确实从具有足够容量的同一 slice append 。为了解决它,制作一个新的 slice 并复制内存。

tempResult := make([]int,len(pre)+1)
copy(tempResult,pre)
tempResult[len(pre)] = i

关于go - 将值附加到 slice 时,值与原始值不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50859784/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com