Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting "bytes.Buffer does not implement io.Writer" error message

Tags:

go

I'm trying to have some Go object implement io.Writer, but writes to a string instead of a file or file-like object. I thought bytes.Buffer would work since it implements Write(p []byte). However when I try this:

import "bufio"
import "bytes"

func main() {
    var b bytes.Buffer
    foo := bufio.NewWriter(b)
}

I get the following error:

cannot use b (type bytes.Buffer) as type io.Writer in function argument:
bytes.Buffer does not implement io.Writer (Write method has pointer receiver)

I am confused, since it clearly implements the interface. How do I resolve this error?

like image 323
Kevin Burke Avatar asked May 04 '14 10:05

Kevin Burke


3 Answers

Pass a pointer to the buffer, instead of the buffer itself:

import "bufio"
import "bytes"

func main() {
    var b bytes.Buffer
    foo := bufio.NewWriter(&b)
}
like image 156
Kevin Burke Avatar answered Nov 15 '22 18:11

Kevin Burke


package main

import "bytes"
import "io"

func main() {
    var b bytes.Buffer
    _ = io.Writer(&b)
}

You don't need use "bufio.NewWriter(&b)" to create an io.Writer. &b is an io.Writer itself.

like image 31
aQua Avatar answered Nov 15 '22 16:11

aQua


Just use

foo := bufio.NewWriter(&b)

Because the way bytes.Buffer implements io.Writer is

func (b *Buffer) Write(p []byte) (n int, err error) {
    ...
}
// io.Writer definition
type Writer interface {
    Write(p []byte) (n int, err error)
}

It's b *Buffer, not b Buffer. (I also think it is weird for we can call a method by a variable or its pointer, but we can't assign a pointer to a non-pointer type variable.)

Besides, the compiler prompt is not clear enough:

bytes.Buffer does not implement io.Writer (Write method has pointer receiver)


Some ideas, Go use Passed by value, if we pass b to buffio.NewWriter(), in NewWriter(), it is a new b (a new buffer), not the original buffer we defined, therefore we need pass the address &b.


bytes.Buffer is defined as:

type Buffer struct {
    buf       []byte   // contents are the bytes buf[off : len(buf)]
    off       int      // read at &buf[off], write at &buf[len(buf)]
    bootstrap [64]byte // memory to hold first slice; helps small buffers avoid allocation.
    lastRead  readOp   // last read operation, so that Unread* can work correctly.
}

using passed by value, the passed new buffer struct is different from the origin buffer variable.

like image 20
wmlhust Avatar answered Nov 15 '22 16:11

wmlhust