嵌入式介面

我对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是Reader和Writer,因此我希望这段代码能够正常工作。我确实尝试使用以下方法转换接口类型:


readStuff(sl.(buffio.Reader))

但这也不起作用。所以我有两个问题:


为什么不起作用?

这个问题的发展哲学是什么?


慕田峪9158850
浏览 182回答 2
2回答

catspeake

它们是不同的类型。但是,abufio.ReadWriter包含一个指向bufio.Reader类型和bufio.Writer类型的指针,作为其结构的元素。因此,传递正确的密码应该很容易。试试这个:func test(sl bufio.ReadWriter){    readStuff(sl.Reader)    [...]    writeStuff(sl.Writer)}// Changed this bufio.Reader to a pointer receiverfunc readStuff(sl *bufio.Reader) {    [...]}

至尊宝的传说

bufio.ReadWriter是具体类型,而不是接口。但是,它确实满足接口(io.ReadWriter),因此可以将其分配给适当接口类型的变量/函数自变量。然后,它将按您预期的方式工作(您的代码实际上不使用任何接口):package mainimport (        "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.ReadWriter,而不仅仅是特定的东西。这暗示了您有关“哲学”问题的提示。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go