"Bytes.Buffer io.Writer uygulamıyor" hata mesajını alıyorum


104

Bazı Go nesnesinin io.Writer uygulamasını sağlamaya çalışıyorum, ancak dosya veya dosya benzeri bir nesne yerine bir dizeye yazıyor. bytes.BufferUyguladığından beri işe yarayacağını düşündüm Write(p []byte). Ancak bunu denediğimde:

import "bufio"
import "bytes"

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

Aşağıdaki hatayı alıyorum:

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)

Arayüzü açıkça uyguladığı için kafam karıştı. Bu hatayı nasıl çözerim?


2
Bu sorunla en az iki kez karşılaştım ve bir çözüm için Google'da arama yapmak gerçekten yardımcı olmadı.
Kevin Burke

11
Bir bufio oluşturmanın gerekli olmadığını unutmayın. & B'yi io.Writer olarak kullan
Vivien

Yanıtlar:


157

Arabelleğin kendisi yerine arabelleğe bir işaretçi iletin:

import "bufio"
import "bytes"

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

4
Bununla karşılaştım ve neden böyle olduğunu öğrenmekle ilgilenirim. Go'daki işaretlere aşina değilim.
2014

2
Teşekkürler Kevin, bu basit hata bunu Google'da araştırana kadar bir saatimi aldı. :)
Nelo Mitranim

8
@hourback, arayüzün uygulanma şekli ile ilgilidir. Aslında Go'da bir arayüz uygulamanın yolları var. Değer veya işaret alıcıları ile. Bunun Go için gerçekten tuhaf bir değişiklik olduğunu düşünüyorum. Arayüz değer alıcıları kullanılarak gerçekleştirilirse, her iki şekilde de sorun yoktur, ancak arayüz işaretçi alıcıları kullanılarak gerçekleştiriliyorsa, arayüzü kullanmak istiyorsanız değere bir işaretçi iletmeniz gerekir. Yazarın, yazarın kafasının nerede olduğunu takip etmek için tamponu mutasyona uğratması gerektiği için mantıklı.
John Leidegren

26
package main

import "bytes"
import "io"

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

Bir io.Writer oluşturmak için "bufio.NewWriter (& b)" kullanmanız gerekmez. & b bir io.Writer'ın kendisidir.


1
Bu doğru cevap olmalı. Arabellekten yeni bir yazıcı oluşturmaya çalışırsanız, ara bellek baytlarını doğrudan getiremezsiniz, bu da işleri çok daha karmaşık hale getirir.
onetwopunch

Bunun ne yaptığını anlamak istedim? Sadece b'nin Writer arayüzünü uygulayıp uygulamadığını kontrol etmek için mi? _ = io.Writer (& b)
Aki

8

Sadece kullan

foo := bufio.NewWriter(&b)

Çünkü bytes.Buffer'ın io.Writer'ı uygulama şekli

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

O var b *Buffer, değil b Buffer. (Ayrıca bir yöntemi bir değişken veya onun göstericisi ile çağırabilmemizin tuhaf olduğunu düşünüyorum, ancak işaretçi olmayan bir değişkene bir işaretçi atayamayız.)

Ayrıca, derleyici istemi yeterince açık değil:

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


Bazı fikirler, Go kullanım Passed by valuebiz geçmesi halinde, biçin buffio.NewWriter(), NewWriter () içinde, yeni bir olduğunu bbu nedenle adresini geçmesi gerekmez, (yeni bir tampon) değil, biz tanımlanan orijinal tampon &b.

Tekrar ekleyin, bytes.Buffer tanımlanır:

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

kullanılarak passed by value, geçirilen yeni tampon yapısı, başlangıç ​​tampon değişkeninden farklıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.