为了账号安全,请及时绑定邮箱和手机立即绑定

生成二进制序列时切片附加无法按预期工作

生成二进制序列时切片附加无法按预期工作

Go
交互式爱情 2023-08-07 15:04:24
我有这段代码可以生成长度为 n 的所有二进制序列。所以:allBitsSeqs(2) gives a 1-by-n int slice  [[1 1][0 0] [1 0] [0 1]]这是代码:func allBitSeqs(n int) [][]int {          seq := [][]int{{1}, {0}}    for floor := 1; floor < n; floor++ {        remember := [][]int{}        for i := 0; i < len(seq); i++ {            one := append(seq[i], 1)            remember = append(remember, one)            zero := append(seq[i], 0)            remember = append(remember, zero)        }        seq = remember    }    return seq}游乐场链接:https://play.golang.org/p/s40RS7qEKfL问题是,当 n = 4 或更多时,我得到:[[1 1 1 0] [1 1 1 0] [1 1 0 0] [1 1 0 0] [1 0 1 0] [1 0 1 0] [1 0 0 0] [1 0 0 0] [0 1 1 0] [0 1 1 0] [0 1 0 0] [0 1 0 0] [0 0 1 0] [0 0 1 0] [0 0 0 0] [0 0 0 0]]注意它们是如何成对重复的。我尝试过一些调试,我认为这与 Go 在需要分配更多空间时如何复制其切片有关。
查看完整描述

1 回答

?
缥缈止盈

TA贡献2041条经验 获得超4个赞

切片是底层数组的视图。如果您有多个切片使用同一个底层数组,并且您不知道切片如何工作,则可能会得到意外的结果。

one := append(seq[i], 1)

比如说,one是一个指向数组的切片,该数组有能力保存添加的元素。像下面这样:

[ 1 1 . . .  ]

数组容量为 5,前两个元素设置为 1(切片长度=2)。再加上1,就变成:

[ 1 1 1 . .]

然后您执行以下操作:

remember = append(remember, one)

这样,您添加了一个指向上面数组的切片,其中 len=3 且容量=5。

然后:

zero := append(seq[i], 0)

请记住 seq[i] 仍然指向同一个数组。另外,seq[i]的len=2。所以数组就变成了:

[ 1 1 0 . . ]

那是你的zero。但是,当您添加 0 时,您也更改了 slice one。你最终会得到 和zeroone指向[1 1 0 . .]

长话短说:当您将切片分配给变量时,您将视图分配给数组。如果修改底层数组的内容,视图的内容也会更改。

修复方法:创建一个新切片、复制数据并存储该副本。


查看完整回答
反对 回复 2023-08-07
  • 1 回答
  • 0 关注
  • 71 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信