附加到 2d 切片时的奇怪行为
Strange behavior when appending to a 2d slice
我正在使用 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
为什么会发生这种情况,我该如何解决?
有趣的是,如果我不使用拆分而是像这样定义值,就不会发生这种情况:
values := [][]byte{[]byte("first line"), []byte("second line"), []byte("third line")}
您所做的是附加到字符串,而不是附加到数组,这会溢出切片的底层数据结构。这就是数组的其余部分被您附加的字符串覆盖的原因。
澄清一下(情况可能并非总是如此):
数组values
由连续排列的3个[]字节块组成。每个 []byte 块都有固定长度(基于其中字符串的长度)。所以 values[0]
的长度为 10(不包括 '\n' 或 '\0')。现在,如果您尝试将 "-inserted text-"
附加到该块,字符将 "flow" 进入连续的块 values[1]
,将 values[1]
中的字符替换为 [= 中的字符12=]。这就是为什么您会在 values[1]
和 values[1]
.
中看到这些字符的一部分
底层存储是共享的,因此要获得您想要的效果,您需要存储从 bytes.Split
返回的切片的副本,而不仅仅是返回的切片。当您追加到返回的第一个切片时,您实际上是在踩踏所有后续切片。
我正在使用 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
为什么会发生这种情况,我该如何解决?
有趣的是,如果我不使用拆分而是像这样定义值,就不会发生这种情况:
values := [][]byte{[]byte("first line"), []byte("second line"), []byte("third line")}
您所做的是附加到字符串,而不是附加到数组,这会溢出切片的底层数据结构。这就是数组的其余部分被您附加的字符串覆盖的原因。
澄清一下(情况可能并非总是如此):
数组values
由连续排列的3个[]字节块组成。每个 []byte 块都有固定长度(基于其中字符串的长度)。所以 values[0]
的长度为 10(不包括 '\n' 或 '\0')。现在,如果您尝试将 "-inserted text-"
附加到该块,字符将 "flow" 进入连续的块 values[1]
,将 values[1]
中的字符替换为 [= 中的字符12=]。这就是为什么您会在 values[1]
和 values[1]
.
底层存储是共享的,因此要获得您想要的效果,您需要存储从 bytes.Split
返回的切片的副本,而不仅仅是返回的切片。当您追加到返回的第一个切片时,您实际上是在踩踏所有后续切片。