内容有点多,请大家耐心看完:
大家好,我最近看了一下Russ Cox关于interface的博文http://research.swtch.com/interfaces 其中提到接口的数据结构其实由连个字段组成:其中一个保存与该接口相关连的具体数据的值(当然也可能是指向值的指针);而另一个则存储的是指向接口表的指针,该表中既存储着关联该接口的具体数据的类型,又包含了实现该接口所需所有方法的指针,而不属于该接口的方法是不会保存进来的。
后来,我又看到在另一篇博文中,有如下的代码:
```golang
var r io.Reader
tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
if err != nil {
return nil, err
}
r = tty
var w io.Writer
w = r.(io.Writer)
```
io.Reader是仅含有Read()方法的接口,而io.Writer则仅含有Write()方法,也就是说上述的代码完成了两个完全无关的接口的转换,只要与Reader接口相关连的具体对象同时实现了这两种接口。
于是我就有了疑惑:如果如Russ Cox在博文中所说,接口对象只是存储了与其相关连的具体对象的部分数据,而非全部(因为与接口不相符的方法,是不会在接口表中有条目的)。那么上述代码中r自身的数据结构中就应该只存有Read()方法的,它是怎么成功通过io.Writer类型断言,并成功转换为Writer接口的呢。
我个人认为,似乎只有r中保存有关联的具体对象的所有方法,上述代码才能成立,所以我觉得这两篇博文有矛盾之处。`当然我并不是说这两篇文章有什么错误`,我只是觉得,我这样的菜鸟,对go语言的理解不可能透彻,一定是我疏忽了某些内容,才会有上述的疑惑。所以想请各位gopher帮我解解惑,我将不胜感激。
**Type assertions**
For an expression x of interface type and a type T, the primary expression
x.(T)
asserts that x is not nil and that the value stored in x is of type T. The notation x.(T) is called a type assertion.
上面的内容摘录自[Golang Specification](https://golang.org/ref/spec#Type_assertions)
执行x.(T)主要是看x所存储的Value,你可以试着对r和w都reflect.ValueOf一下,其实际都是*os.File类型
#2
更多评论
== 你的这个问题,我没有实际验证,仅从字面上这么理解,你看是否正确 ==
你的代码,其实是
var r io.Reader
var w io.Writer
tty := os.OpenFile("")
r = tty
w = r.(io.Writer)
记得这里 http://ilovers.sinaapp.com/doc/golang-specification.html#Assignability
曾经说过:
x = T
的赋值可以进行的前提是:T是一个接口类型,而x 实现了接口T;
至于 `w = r.(io.Writer)`,其实是 `w = tty.(io.Writer)`
不是 r,w 的接口类型被转换了, 而是 w 从tty 中获取接口。
不知道我这样理解是否正确, 欢迎讨论哈。
#1