8

私はまだ Go に慣れていないので、組み込みインターフェースのサブタイプを使用できないことに驚きました。ここに私が何を意味するかを説明するための小さな例があります:

func test(sl bufio.ReadWriter){
    // cannot use sl(type bufio.ReadWriter) as type bufio.Reader in function argument
    readStuff(sl) 
    [...]
    writeStuff(sl) // same kind of error
}

func readStuff(sl bufio.Reader){
    [...]
}

すべてのインターフェイスは同じメモリ レイアウトを持ち、ReadWriter はリーダーとライターであるため、このコードが機能することを期待していました。インターフェイスタイプを次のように変換しようとしました:

readStuff(sl.(buffio.Reader))

しかし、それも機能しません。だから私は2つの質問があります:

  • うまくいかないのはなぜですか?
  • その問題についての哲学は何ですか?
4

2 に答える 2

7

それらは異なるタイプです。ただし、 aには、その構造体の要素として型と型のbufio.ReadWriter両方へのポインターが含まれています。したがって、正しいものを渡すのは簡単です。これを試して:bufio.Readerbufio.Writer

func test(sl bufio.ReadWriter){
    readStuff(sl.Reader)
    [...]
    writeStuff(sl.Writer)
}

// Changed this bufio.Reader to a pointer receiver
func readStuff(sl *bufio.Reader) {
    [...]
}
于 2012-12-16T21:03:00.377 に答える
6

bufio.ReadWriterは具体的な型であり、インターフェイスではありません。ただし、インターフェイス (io.ReadWriter) を満たしているため、適切なインターフェイス タイプの変数/関数引数に割り当てることができます。次に、予想どおりに動作します (コードは実際にはインターフェイスを使用しません)。

package main

import (
        "bufio"
        "bytes"
        "fmt"
        "io"
        "log"
)

func readStuff(r io.Reader) {
        b := make([]byte, 10)
        n, err := r.Read(b)
        if err != nil && err != io.EOF {
                log.Fatal(err)
        }
        fmt.Printf("readStuff: %q\n", b[:n])
}

func writeStuff(w io.Writer) {
        b := []byte("written")
        n, err := w.Write(b)
        if n != len(b) {
                log.Fatal("Short write")
        }

        if err != nil {
                log.Fatal(err)
        }
}

func test(rw io.ReadWriter) {
    readStuff(rw)
    writeStuff(rw)
}

func main() {
        r := io.Reader(bytes.NewBufferString("source"))
        var uw bytes.Buffer
        w := io.Writer(&uw)
        rw := bufio.NewReadWriter(bufio.NewReader(r), bufio.NewWriter(w))
        test(rw)
        rw.Flush()
        fmt.Printf("The underlying bytes.Buffer writer contains %q\n", uw.Bytes())
}

こちらも)


出力:

readStuff: "source"
The underlying bytes.Buffer writer contains "written"

この方法では、特定のものだけでなく、test任意の を消費できます。io.ReadWritergo「哲学」についてのあなたの質問に対するヒントです。

于 2012-12-17T07:09:19.057 に答える