这种类型断言是否有效?

huangapple go评论85阅读模式
英文:

Is this type assertion ever valid?

问题

我正在阅读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))
}

其中

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

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

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

英文:

I am reading the source code for Go's io package and I came across a snippet I don't fully understand. Here it is

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

where

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

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

The type assertion w.(stringWriter) asserts that the dynamic type of w (i.e. Writer) implements the stringWriter interface. I don't see how this is possible given the type definitions of stringWriter and Writer. Assuming that this code is correct, what is it that I am missing?

答案1

得分: 5

你可以轻松地构建一个实现WriterstringWriter的类型:

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

因此,将StringWriter的实例传递给io.WriteString会调用StringWriter.WriteString

io.WriteString的逻辑是:如果写入器具有WriteString方法,则使用该方法,否则回退到string[]byte的转换。为了测试实例是否实现了某个方法,使用接口,因为接口只是方法集,可以轻松地进行测试。

英文:

You can easily build a type which implements Writer as well as 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)) 
}

So passing an instance of StringWriter to io.WriteString results in StringWriter.WriteString
being called.

The logic behind io.WriteString is: Use WriteString on the writer if it has such a method
or fall back to string to []byte conversion otherwise. To test whether the instance implements
a method or not, interfaces are used, as these are just method sets and can be tested for easily.

huangapple
  • 本文由 发表于 2013年6月14日 17:29:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/17105336.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定