Don’t Reuse That []byte Buffer
Go’s bytes.Buffer
is an excellent tool to hold temporary data. Except, you need to remember the difference between string
and []byte
. Take a look at the sample below, and see if you can deduce how it will behave without running it.
There two things to note:
Reset()
resets the underlying[]byte
buffer inbytes.Buffer
, but it reuses for subsequent reads and writes.- In Go, a
string
is immutable, and you can only create new ones, whereas slices share the same underlying storage
This means that (bytes.Buffer).Bytes()
and (bytes.Buffer).String()
have slightly different semantics. The return value from the former is a slice with shared storage with the the bytes.Buffer
object, where as the latter returns a completely standalone object.
So in our previous example, you will see that foobytes
will contain the same data that barbytes
contain, except for the fact that foobytes
is the view into the same []byte
with len=13 (the length of “Hello, World!”) as opposed to len=15 (the length of “Goodbye, World!”)
The takeaway here is, if you need to use the result of writing to bytes.Buffer
, but want to reuse bytes.Buffer
object, you will need to copy the data that the underlying buffer in bytes.Buffer
to another []byte
or string
in order to make it independent from subsequent modifications to the object.
Hope that helps someone in the future. Happy (Cautious) Go Hacking!