"bytes.Buffer가 io.Writer를 구현하지 않습니다"오류 메시지가 표시됨


98

일부 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)

인터페이스를 명확하게 구현하기 때문에 혼란 스럽습니다. 이 오류를 어떻게 해결합니까?


2
나는이 문제를 적어도 두 번 만났고, 해결책을 찾기위한 인터넷 검색은 정말 도움이되지 않았습니다.
Kevin Burke

11
bufio를 만들 필요는 없습니다. & b를 io.Writer로 사용하면됩니다.
Vivien

답변:


153

버퍼 자체 대신 포인터를 버퍼에 전달합니다.

import "bufio"
import "bytes"

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

4
나는 이것을 만났고 왜 그런지 배우고 싶을 것입니다. Go의 포인터에 익숙하지 않습니다.
hourback

1
감사합니다 Kevin,이 간단한 실수는 제가 이것을 검색 할 때까지 한 시간이 걸렸습니다. :)
Nelo Mitranim 2014

7
@hourback은 인터페이스가 구현되는 방식과 관련이 있습니다. 실제로 Go에서 인터페이스를 구현하는 방법이 있습니다. 값 또는 포인터 수신기와 함께. 저는 이것이 Go에 대한 정말 독특한 비틀기라고 생각합니다. 인터페이스가 값 수신기를 사용하여 구현 된 경우 어느 쪽이든 괜찮지 만 인터페이스가 포인터 수신기를 사용하여 구현 된 경우 인터페이스를 사용하려면 값에 대한 포인터를 전달해야합니다. 작성자가 작성자 헤드의 위치를 ​​추적하기 위해 버퍼를 변경해야하기 때문에 의미가 있습니다.
John Leidegren

23
package main

import "bytes"
import "io"

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

io.Writer를 만들기 위해 "bufio.NewWriter (& b)"를 사용할 필요가 없습니다. & b는 io.Writer 자체입니다.


이것이 정답이되어야합니다. 버퍼에서 새 작성기를 만들려고하면 버퍼 바이트를 직접 가져올 수 없으므로 상황이 훨씬 더 복잡해집니다.
onetwopunch

8

그냥 사용

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)


일부 아이디어는 이동 사용은 Passed by value우리가 통과하는 경우 bbuffio.NewWriter(), NewWriter ()에, 그것은 새로운 b그러므로 우리는 주소를 전달할 필요, (새로운 버퍼),하지 우리가 정의 된 원래 버퍼 &b.

다시 추가하면 bytes.Buffer가 정의됩니다.

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하면 전달 된 새 버퍼 구조체가 원본 버퍼 변수와 다릅니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.