英文:
Write to beginning of the buffer in Golang?
问题
我有:
var buffer bytes.Buffer
s := "something to do"
for i := 0; i < 10; i++ {
buffer.WriteString(s)
}
这段代码将字符串追加到缓冲区中,是否可能向缓冲区的开头写入数据?
英文:
I have:
var buffer bytes.Buffer
s := "something to do"
for i := 0; i < 10; i++ {
buffer.WriteString(s)
}
Which appends to the buffer, is it possible to write to the beginning of a buffer?
答案1
得分: 6
由于bytes.Buffer
中的buf
底层不可导出,您可以使用以下方法:
buffer.WriteString("B")
s := buffer.String()
buffer.Reset()
buffer.WriteString("A")
buffer.WriteString(s)
您可以在The Go Playground上尝试这个示例代码:
package main
import (
"bytes"
"fmt"
)
func main() {
var buffer bytes.Buffer
buffer.WriteString("B")
s := buffer.String()
buffer.Reset()
buffer.WriteString("A" + s)
fmt.Println(buffer.String())
}
输出结果为:
AB
英文:
Since the underlying buf
not exported from bytes.Buffer
, you may use:
buffer.WriteString("B")
s := buffer.String()
buffer.Reset()
buffer.WriteString("A")
buffer.WriteString(s)
Try this The Go Playground:
package main
import (
"bytes"
"fmt"
)
func main() {
var buffer bytes.Buffer
buffer.WriteString("B")
s := buffer.String()
buffer.Reset()
buffer.WriteString("A" + s)
fmt.Println(buffer.String())
}
output:
AB
答案2
得分: 6
在开头插入是不可能的,参考Amd的答案找到一个“变通方法”。如果要覆盖开头的内容,请继续阅读。
请注意,内部的字节切片Buffer.buf
是不可导出的,但是方法Buffer.Bytes()
返回一个切片,与Buffer.buf
内部切片共享相同的底层数组。
这意味着,如果你通过调用Bytes.NewBuffer()
创建一个新的bytes.Buffer
,并将此切片重新切片为零长度和保留容量后传递,你可以写入到缓冲区的开头,覆盖第一个缓冲区的原始数据。
看下面的例子:
buf := &bytes.Buffer{}
buf.WriteString("Hello World")
fmt.Println("buf:", buf)
buf2 := bytes.NewBuffer(buf.Bytes()[:0])
buf2.WriteString("Gopher")
fmt.Println("buf:", buf)
fmt.Println("buf2:", buf2)
输出结果(在Go Playground上尝试):
buf: Hello World
buf: Gopher World
buf2: Gopher
注意:使用这种技术,你还可以通过使用所需索引进行重新切片而不是0
来覆盖任意位置的内容,并传递该切片。例如:
buf := &bytes.Buffer{}
buf.WriteString("Hello World")
fmt.Println("buf:", buf)
buf2 := bytes.NewBuffer(buf.Bytes()[6:6]) // 从“Hello”之后开始
buf2.WriteString("Gopher")
fmt.Println("buf:", buf)
fmt.Println("buf2:", buf2)
输出结果(在Go Playground上尝试):
buf: Hello World
buf: Hello Gopher
buf2: Gopher
请注意,通过Buffer.Bytes()
返回的切片对内容的“操作”只能在Buffer
被修改之前成功,之后Buffer
有可能分配一个新的底层数组,你所拥有的那个切片将会“分离”(因此对它的进一步修改将不会反映在原始的Buffer
中):
该切片仅在下一次缓冲区修改之前有效(也就是说,仅在下一次调用Read、Write、Reset或Truncate等方法之前有效)。
英文:
Inserting to the beginning is not possible, see Amd's answer for a "workaround". For overwriting content at the beginning, read on.
Note that the internal byte slice Buffer.buf
is not exported, but the method Buffer.Bytes()
returns a slice sharing the same backing array as the Buffer.buf
internal slice.
This means if you create a new bytes.Buffer
by calling Bytes.NewBuffer()
, and pass this slice after reslicing it to zero length and capacity retained, you can write to the beginning of the buffer, overwriting original data of the first buffer.
See this example:
buf := &bytes.Buffer{}
buf.WriteString("Hello World")
fmt.Println("buf:", buf)
buf2 := bytes.NewBuffer(buf.Bytes()[:0])
buf2.WriteString("Gopher")
fmt.Println("buf:", buf)
fmt.Println("buf2:", buf2)
Output (try it on the Go Playground):
buf: Hello World
buf: Gopher World
buf2: Gopher
Note: Using this technique, you can also overwrite content at arbitrary position, by reslicing using the desired index instead of 0
and passing the slice. For example:
buf := &bytes.Buffer{}
buf.WriteString("Hello World")
fmt.Println("buf:", buf)
buf2 := bytes.NewBuffer(buf.Bytes()[6:6]) // Start after the "Hello"
buf2.WriteString("Gopher")
fmt.Println("buf:", buf)
fmt.Println("buf2:", buf2)
Output (try it on the Go Playground):
buf: Hello World
buf: Hello Gopher
buf2: Gopher
Note that the "manipulation" of the content through the slice returned by Buffer.Bytes()
may only succeed until the Buffer
is modified, after that there's a chance that Buffer
allocates a new backing array and the one you have will be "detached" (and so further modification on it will not be reflected in the original Buffer
):
> The slice is valid for use only until the next buffer modification (that is, only until the next call to a method like Read, Write, Reset, or Truncate).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论