这种类型的断言是否有效?

Ser*_*kov 2 go

我正在阅读Go的io包的源代码,我遇到了一个我不完全理解的片段.这里是

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))
}
Run Code Online (Sandbox Code Playgroud)

哪里

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

type Writer interface {
    Write(p []byte) (n int, err error)
}
Run Code Online (Sandbox Code Playgroud)

类型断言w.(stringWriter)断言w的动态类型(即Writer)实现了stringWriter接口.鉴于stringWriter和Writer的类型定义,我不知道这是如何可行的.假设这段代码是正确的,我错过了什么?

nem*_*emo 5

您可以轻松地构建它实现了一个类型Writer,以及stringWriter:

type StringWriter struct{}

func (s StringWriter) Write(in []byte) (int, error) { 
    return 0, nil 
}
func (s StringWriter) WriteString(s string) (int, error) { 
    return s.Write([]byte(s)) 
}
Run Code Online (Sandbox Code Playgroud)

因此,通过实例StringWriter,以io.WriteString结果StringWriter.WriteString 被调用.

背后的逻辑io.WriteString是:WriteString如果它有这样的方法,则string[]byte编写器上使用,否则回退到转换.要测试实例是否实现方法,请使用接口,因为这些只是方法集,可以轻松测试.