我使用2D切片字节来表示一堆行,但是当我附加到其中一行时,我会得到一些非常奇怪的行为。
以下是一个例子:
package main
import (
"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 line
second line
third line
After:
first line-inserted text-
second line
third line
但输出是:
Before:
first line
second line
third line
After:
first line-inserted text-
inserted te
t-ird line
https://play.golang.org/p/iNw6s1S66U
为什么会发生这种情况,我该如何解决?
有趣的是,如果我不使用split而不是像这样定义值,则不会发生这种情况:
values := [][]byte{[]byte("first line"), []byte("second line"), []byte("third line")}
答案 0 :(得分:2)
底层存储是共享的,因此要获得所需的效果,您需要存储从bytes.Split
返回的切片的副本,而不仅仅是返回的切片。当您追加到返回的第一个切片时,您基本上会在以下切片上踩踏。
答案 1 :(得分:1)
你正在做的是追加到字符串,而不是附加到数组,那就是溢出了切片的底层数据结构。这就是为什么数组的其余部分被你追加的字符串覆盖的原因。
澄清(情况可能并非总是如此):
数组values
由连续排列的3 []字节块组成。每个[]字节块具有固定长度(基于其中的字符串长度)。因此values[0]
的长度为10(不包括'\ n'或'\ 0')。现在,如果您尝试将"-inserted text-"
附加到该块,则字符将“流”到连续的块values[1]
中,将values[1]
中的字符替换为"-inserted text-"
中的字符}。这就是为什么你会在values[1]
和values[1]
中看到这些字符的一部分。