Go 中的接口是如何实现的?
在检查 Go 中的接口时,不同的视角可能会导致看似相反的理解。
方案表示
在“反射定律”一文中,接口值包含一个(值,类型)对。例如,将 io.Reader 分配给变量 r 会产生 r = (tty, *os.File)。这里,tty 是值,而 *os.File 表示基础值的类型。尽管 Read 方法有接口限制,但内部值保留了完整的类型信息。
动态调度
相反,另一篇文章指出类型的 itable 实现具体接口方法。对于实现 Stringer 的 Binary 类型,其 itable 仅包含 String 方法。这意味着 itable 应该反映接口值的静态类型,而不是底层值的类型。
澄清
这两个观点是相辅相成的。 “反射定律”检查通过反射看到的接口值,提供简化的表示。第二篇文章重点介绍接口底层的动态调度机制,揭示具体实现方法的参与。
变量 r 的值确实包含 tty,并且具有静态类型 io.Reader,它是一个包装接口提供对 Read 方法的访问。然而,底层值 tty 保留其类型为 *os.File,包括 Read 之外的其他方法。
在 Go 中,接口是通过动态调度实现的,其中运行时根据具体情况解析调用哪个方法实现包装值的类型。 itable 存储每个接口方法的实现细节。
以上是## Go 中的接口是如何实现的:静态类型还是动态调度?的详细内容。更多信息请关注PHP中文网其他相关文章!