【问题标题】:Embedded Interface嵌入式接口
【发布时间】:2012-12-16 20:56:23
【问题描述】:

我对 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))

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

  • 为什么它不起作用?
  • 关于这个问题的围棋哲学是什么?

【问题讨论】:

    标签: go


    【解决方案1】:

    它们是不同的类型。但是,bufio.ReadWriter 包含一个指向 bufio.Reader 类型和 bufio.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) {
        [...]
    }
    

    【讨论】:

    • 我还有第二个问题:如果我的所有参数都是切片而不是单个参数怎么办。有什么优雅的方法可以将 ReadWriter 切片转换为 Reader 切片?
    • 我认为最优雅的解决方案是创建一个新切片并通过 for 循环填充它。
    【解决方案2】:

    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())
    }
    

    (也叫here


    输出:

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

    这样test 可以消费任何io.ReadWriter,而不仅仅是一个特定的。这暗示了您关于“哲学”的问题。

    【讨论】:

      猜你喜欢
      • 2018-12-09
      • 1970-01-01
      • 2015-05-16
      • 1970-01-01
      • 2018-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多