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

附加到二维切片时的奇怪行为

附加到二维切片时的奇怪行为

Go
不负相思意 2022-01-10 16:58:30
我使用二维字节切片来表示一堆行,但是当我附加到其中一行时,我得到了一些非常奇怪的行为。这是一个例子:package mainimport (    "bytes"    "fmt")func main() {    str := []byte("first line\nsecond line\nthird line")    values := bytes.Split(str, []byte("\n"))    fmt.Println("Before:")    fmt.Println(string(values[0]))    fmt.Println(string(values[1]))    fmt.Println(string(values[2]))    fmt.Println()    values[0] = append(values[0], []byte("-inserted text-")...)    fmt.Println("After:")    fmt.Println(string(values[0]))    fmt.Println(string(values[1]))    fmt.Println(string(values[2]))}我希望这个程序的输出是Before:first linesecond linethird lineAfter:first line-inserted text-second linethird line但相反的输出是:Before:first linesecond linethird lineAfter:first line-inserted text-inserted tet-ird linehttps://play.golang.org/p/iNw6s1S66U为什么会发生这种情况,我该如何解决?有趣的是,如果我不使用 split 而是定义如下值,则不会发生这种情况:values := [][]byte{[]byte("first line"), []byte("second line"), []byte("third line")}https://play.golang.org/p/pEflrhKLd4
查看完整描述

2 回答

?
SMILET

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

底层存储是共享的,因此要获得所需的效果,您需要存储从 返回的切片的副本bytes.Split,而不仅仅是返回的切片。当您附加到返回的第一个切片时,您实际上是在踩到后面的切片。


查看完整回答
反对 回复 2022-01-10
?
慕斯709654

TA贡献1840条经验 获得超5个赞

您正在做的是附加到字符串,而不是附加到数组,这会溢出切片的底层数据结构。这就是为什么数组的其余部分被您附加的字符串覆盖的原因。

澄清(可能并非总是如此):

该数组values由连续排列的 3 个 []byte 块组成。每个 []byte 块都有固定的长度(基于其中字符串的长度)。所以values[0]长度为 10(不包括 '\n' 或 '\0')。现在,如果您尝试附加"-inserted text-"到该块,字符将“流入”到连续块中values[1], 用 中的字符替换values[1]其中的字符"-inserted text-"。这就是为什么您会在values[1]和 中看到这些字符的一部分values[1]


查看完整回答
反对 回复 2022-01-10
  • 2 回答
  • 0 关注
  • 127 浏览
慕课专栏
更多

添加回答

举报

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