I'd like to write to slice of bytes through the use of a writer.
I've tried that:
var out []byte = make([]byte, 7)
w := bytes.NewBuffer(out)
var foo []byte = []byte{84, 240, 4, 66, 80, 4, 79}
w.Write(foo)
for i:=0; i<len(out); i++ {
print(out[i], "\n")
}
but all I get is zeroes when printing.
What am I doing wrong please?
Thanks,
Mathieu
Your slice `out` has capacity AND LENGTH 7. There is no room in
it for bytes.Write to write any bytes, so it has to grow a new slice
(with initial contents copied from `out`) to write to.
[the documentation for NewBuffer says:
It can also be used to to size the internal buffer for writing.
To do that, buf should have the desired capacity but a length
of zero.
which is why I knew about the length-and-capacity issue.
]
So your `out` slice is unchanged. You can change the make call
to give out capacity 7 and length 0:
var out []byte = make([]byte, 0, 7)
However, this doesn't visibly help, because the slice `out` has
been passed in to NewBuffer by value -- so changes to the
slice that bytes.Write is using /will not affect/ the length and
capacity of `out`. [They will change the underlying array, until
it has to expand the slice.]
Fortunately Buffer has a method Bytes() which returns a slice
of the (unread, but you didn't read anything, so that's OK) bytes
of the buffer, so you can print that out instead:
package main
import "bytes"
import "fmt"
func main() {
var out []byte = make([]byte, 0, 7)
w := bytes.NewBuffer(out)
var foo []byte = []byte{84, 240, 4, 66, 80, 4, 79}
n, err := w.Write(foo)
fmt.Printf( "w = %v\n", w.Bytes() )
}
Or you could reslice `out` and print its bytes out to show that
the underlying array has been used:
fmt.Printf( "w = %v\n", out[0:7] )
Chris
--
Chris "allusive" Dollin
Only if you want to initialise the new buffer with no bytes to read.
(Which is true in the OPs case, but not true in general.)
or write:
It is intended to prepare a Buffer to read existing data. It
can also be used to to size the internal buffer for writing.
Second sentence in the quote.
> and Write(foo) is to append. I guess Write is a misnomer, Append
> is better.
Write is better, because then bytes.Buffer satisfies the io.Writer
interface.
Here out is the initial content of the buffer.
But the buffer is a separate thing than out.
It would be very surprising (in Go) if passing
out to a function could later cause out to change
its value (and len(out) is part of its value).
> var foo []byte = []byte{84, 240, 4, 66, 80, 4, 79}
> w.Write(foo)
> for i:=0; i<len(out); i++ {
> print(out[i], "\n")
> }
Right: print w.Bytes() instead. A simple version of your program:
package main
import (
"bytes"
"fmt"
)
func main() {
var w bytes.Buffer
w.Write([]byte("hello"))
fmt.Println(w.Bytes())
}
Russ
And the byte array that the slice refers to isn't?
Chris
--
Chris "it's factal all the way down" Dollin
No, the value of the slice is [ptr to elem 0, len, cap].
http://research.swtch.com/2009/11/go-data-structures.html
Russ
Yes, I understand the data structure just fine, but that
particular use of the term "value of the slice" means that
s[i] = x doesn't change the value of the slice s; consistent
but disconcerting particularly to newcomers to Go, who
may wonder why the length of a slice is part of it but the
value of its elements isn't.
Sure. But that's still what the value of the slice is.
It's just something you have to learn when you come to Go.
Similarly, in C, p[i] = x doesn't change the value of the pointer p.
Russ
USUALLY not. (And I can't think of an instance when it would be the
right thing to happen ...)
Chris
--
Chris "OOPS!" Dollin