Подтвердить что ты не робот

Получение сообщения "bytes.Buffer не реализует io.Writer"

Я пытаюсь реализовать некоторый объект Go io.Writer, но записывает в строку вместо файла или файлового объекта. Я думал, что bytes.Buffer будет работать, поскольку он реализует Write(p []byte). Однако, когда я пробую это:

import "bufio"
import "bytes"

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

Я получаю следующую ошибку:

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)

Я запутался, так как он явно реализует интерфейс. Как устранить эту ошибку?

4b9b3361

Ответ 1

Передайте указатель на буфер вместо самого буфера:

import "bufio"
import "bytes"

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

Ответ 2

package main

import "bytes"
import "io"

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

Вам не нужно использовать "bufio.NewWriter(& b)" для создания io.Writer. & b сам по себе io.Writer.

Ответ 3

Просто используйте

foo := bufio.NewWriter(&b)

Потому что способ bytes.Buffer реализует io.Writer

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

Это b *Buffer, а не b Buffer. (Я также думаю, что это странно, поскольку мы можем вызывать метод по переменной или по ее указателю, но мы не можем назначить указатель на переменную без указателя типа.)

Кроме того, подсказка компилятора недостаточно ясна:

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


Некоторые идеи, Go используют Passed by value, если мы передаем b в buffio.NewWriter(), в NewWriter(), это новый b (новый буфер), а не исходный буфер, который мы определили, поэтому нам нужно передать адрес &b,

Добавьте снова, байты. Буфер определен:

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.
}

используя passed by value, переданная новая структура буфера отличается от исходной переменной буфера.