我能找到的最通用的错误版本如下所示:

package main
import "fmt"

func main() {
    values := []any{1,2,3}
    values = append(values[:1],values[1:])
    fmt.Println(values)
}

这会导致堆栈溢出(有趣的是我在这个站点上发布).如果我从print语句中删除values,并将其替换为其他内容(如0),它不会抛出错误,并且可以正确打印.

如果我使用...来可变地使用附加值,代码运行正常并打印[1 2 3].

我还试着在更改为values和另一条print语句之间添加fmt.Println("This section of code reached successfully!"),但它在错误之前打印,这意味着fmt.Println(values)是导致溢出的行.

我可以自己打印values中的第一项而没有错误,但是自己打印列表中的第二项会导致溢出.

此版本的代码运行时没有错误:

package main
import "fmt"

func main() {
    values := append([]any{1},[]any{2,3})
    fmt.Println(values)
}

这一切为什么要发生?这是我在我的一个项目中遇到的一个错误的更一般的版本.

推荐答案

切片不是数组,它们是数组的视图.以下是一个简化的示例,用于说明:

values := []any{1, 2, 3}
slice := values[1:]       // [2, 3]
values[1] = 100
fmt.Println(slice)        // [9, 3]

如果你改变数组的元素,它的切片也会改变,反之亦然.

现在,当您将数组的一部分附加到同一数组中时,您就进入了自引用内容.

values := []any{1,2,3}
values = append(values[:1],values[1:])  // [1, values[1:]]

values[1:][values[1:]](因为它是values的实时视图,而不是你假设的[2, 3]),也就是[[values[1:]]].所以values不是[1, 2, 3]而是[1, [[[[[[[[[[[[stackoverflow

请注意, struct 本身是好的,虽然不是你想要的.只有当你试图打印它时,它才是一个错误,因为fmt.Println不知道如何处理递归 struct .

为了完成您想要的操作,您需要先复制切片,然后再追加它,这样您就不会最终将递归引用添加到values中.

Go相关问答推荐

杜松子wine -戈尼克背景在 children 围棋例行公事中被取消

如何预编译Golang标准库?

重新赋值变量时未清除动态类型-这是错误吗?

无法获取RPC描述符

从 wincrypt API 到 Go 的 RC2 解密

按位移计算结果中的差异

使用反射在Go中递归迭代 struct 体和集合字段

如何将已知类型转换为指向switch 中类型参数的指针?

在 Go sync.Map 中,为什么这部分实现不一致或者我误解了什么?

加载 docker 镜像失败

接受通道和切片的通用函数

在恒等函数中将类型 T 转换为类型 U

使用 Golang 在字符串中循环重复数据

如何在没有内存分配的情况下压缩和发布文件

Golang Echo Labstack 如何在模板视图中调用函数/方法

Golang - 无法从 pipped Windows 命令中获取结果

如何优雅地映射到 Go 中返回可变长度数组的方法?

跟踪长时间运行的任务的进度 - 正确的方法

Go 使用 struct 作为接口而不实现所有方法

获取单调时间,同 CLOCK_MONOTONIC