go

编码习惯&标准库

1.defer的应用,close文件

Posted by Liangjf on March 30, 2020

编码习惯&标准库[2.从WriteString看io.Writer接口]

go1.13.7 /Go/src/io/io.go:289

众所周知,go中是奉行接口实现解耦,继承,多态的银弹。特别是io.Reader,io.Writer这两个接口,是io的基本接口,标准库和第三方基础组件都实现了这两个函数。

type Reader interface {      
    Read(p []byte) (n int, err error)
}

type Writer interface {      
    Write(p []byte) (n int, err error
)}

下面通过WriteString()来看看接口的用法和作用,基于接口可以实现多态。

Writer当做参数传入函数内部,然后通过类型断言来判断传入的实现接口的真实对象类型,来达到自动调用对应实现的作用。

例如下面WriteString,内部对传入的w参数进行断言,如果实现了StringWriter接口,那么就调用其实现的StringWriter函数,即往实现WriteString的对象中直接写入字符串。若没有实现StringWriter接口,那么就调用Write实现,写入byte切片数据。

type StringWriter interface {      
    WriteString(s string) (n int, err error)
}

func WriteString(w Writer, s string) (n int, err error) {
    if sw, ok := w.(StringWriter); ok {
        return sw.WriteString(s)
    }
    return w.Write([]byte(s))
}

这样相当于实现了多态的特性,根据真实调用的情况而判断出其真实类型而调用其正确的实现方法。

小插曲,查了一下标准库,以下的标准库都实现了 io.Reader 和 io.Writer 二者或者其中之一。证明 io.Reader 和 io.Writer确实是标准库和开源库的基石。也验证了Go的设计理念,大量的“小接口”,组成“大接口”。

  • os.File 同时实现了 io.Reader 和 io.Writer
  • strings.Reader 实现了 io.Reader
  • bufio.Reader/Writer 分别实现了 io.Reader 和 io.Writer
  • bytes.Buffer 同时实现了 io.Reader 和 io.Writer
  • bytes.Reader 实现了 io.Reader
  • compress/gzip.Reader/Writer 分别实现了 io.Reader 和 io.Writer
  • crypto/cipher.StreamReader/StreamWriter 分别实现了 io.Reader 和 io.Writer
  • crypto/tls.Conn 同时实现了 io.Reader 和 io.Writer
  • encoding/csv.Reader/Writer 分别实现了 io.Reader 和 io.Writer
  • mime/multipart.Part 实现了 io.Reader
  • net/conn 分别实现了 io.Reader 和 io.Writer(Conn接口定义了Read/Write)