猿问

Go 中的接口是如何表示的?


> var r io.Reader

tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)

if err != nil {

    return nil, err

}

r = tty

r 示意性地包含 (value, type) 对 (tty, *os.File)。请注意,*os.File 类型实现了 Read 以外的方法;尽管接口值仅提供对 Read 方法的访问,但内部的值携带有关该值的所有类型信息。


另一篇文章说


就我们的示例而言,Stringer 持有类型 Binary 的 itable 列出了用于满足 Stringer 的方法,这只是 String:Binary 的其他方法 (Get) 在 itable 中没有出现。

感觉这两个人是对立的。根据第二篇文章,第一个提取物中的变量 r 应该是 (tty, io.Reader),因为这是 r 的静态类型。相反,文章说 *os.File 是 tty 的类型。如果第二个例子是正确的,那么第一个例子中的图表应该包含由 Binary 类型实现的所有方法。

我哪里错了?


MMTTMM
浏览 170回答 2
2回答

呼如林

这两篇文章在两个非常不同的粒度级别上解释了一个类似的概念。正如沃尔克所说,“反射定律”是对通过反射检查对象时实际发生的情况的基本概述。你的第二用品检查的接口(其中,可通过反射以及解决)和运行时如何做出决议他们的动态调度性能在运行。根据第二篇文章,第一次提取中的变量 r 应该是 (tty, io.Reader)鉴于这种理解,将运行时的接口视为“包装器对象”。它的存在是为了提供有关另一个对象的信息(itable来自您的第二篇文章),以了解在包装对象布局中跳转到的位置(版本之间的实现可能有所不同......但对于大多数语言来说,原理基本相同)。这就是调用Readonr有效的原因.. 首先它会检查itable并跳转到为该os.File类型布置的函数。如果那是一个接口 .. 你会看到另一个取消引用和调度(IIRC 在 Go 中根本不适用)。RE:反射 - 你得到了一个很容易理解的表示,以一(value, type)对的形式(通过reflect.ValueOf和reflect.TypeOf方法)。

明月笑刀无情

两者都是正确的, r "holds" (tty, *os.File) 这就是第二篇文章所说的。请注意,反射法则更高级一些,并且没有像第二篇文章中讨论的那样提及实现细节(可能会在每个版本中发生变化)。第二篇文章的示意图如下:“s 包含示意性的 (b, *Binary)。s 是 Stringer 类型,它的数据是一个值为 200 的 Binary,s 的 itable 包含一个方法 String 和其他 Binary 方法(或*Binary) 未在 itable 中表示,因此无法被 s 访问。请注意,我认为 Go 1.4 中接口的实际实现与第二篇文章(Russ 的?)所述不同。”
随时随地看视频慕课网APP

相关分类

Go
我要回答