「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
私はこの問題に少なくとも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のポインターに慣れていません。
2014年

1
ケビンのおかげで、私がこれをググるまで、この単純な間違いは私の時間の1時間かかりました。:)
Nelo Mitranim 2014年

7
@hourbackインターフェースの実装方法と関係があります。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)


Goが使用するいくつかのアイデアは、NewWriter()でPassed by value渡すbbuffio.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.