我现在正在阅读两篇文章,有点困惑。
本文 -http://blog.golang.org/laws-of-reflection says
> var r io.Reader
tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
if err != nil {
return nil, err
}
r = tty
r 示意性地包含(值,类型)对(tty,*os.File)。
请注意,类型 *os.File 实现了 Read 以外的方法;甚至
尽管接口值仅提供对 Read 方法的访问,
里面的值携带了关于该值的所有类型信息。
另一篇文章说
就我们的示例而言,Stringer 的 itable 持有类型 Binary
列出了用于满足 Stringer 的方法,Stringer 只是 String:
Binary 的其他方法 (Get) 没有出现在 itable 中。
感觉这两个人是对立的。根据第二篇文章,第一篇摘录中的变量 r 应该是 (tty, io.Reader),因为这是 r 的静态类型。相反,文章说 *os.File 是 tty 的类型。如果第二个示例是正确的,那么第一个示例中的图表应该包含 Binary 类型实现的所有方法。
我哪里错了?
这两篇文章在两个截然不同的粒度级别上解释了类似的概念。正如沃尔克所说,“反射定律”是对检查对象时实际发生的情况的基本概述通过反射。您的第二篇文章正在研究接口的动态调度属性(也可以通过反射来解析)以及运行时如何解析它们在运行时.
根据第二篇文章,第一篇摘录中的变量 r 应该是 (tty, io.Reader)
鉴于这种理解,可以将运行时的接口视为“包装对象”。它的存在是为了提供有关另一个对象的信息(itable
从你的第二篇文章中)知道在包装对象布局中跳转到哪里(版本之间的实现可能有所不同..但对于大多数语言来说,原理基本上是相同的)。
这就是为什么调用Read
on r
有效..首先它会检查itable
并跳转到为os.File
类型。如果那是一个接口..您将看到另一个取消引用和分派(IIRC 在 Go 中根本不适用)。
RE:反思 - 你会得到一个易于理解的表示形式,以(value, type)
对(通过reflect.ValueOf
and reflect.TypeOf
方法)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)