Go中的接口如何表示? [英] How are interfaces represented in Go?

查看:176
本文介绍了Go中的接口如何表示?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读两篇文章,并且有点困惑。

本文 - http://blog.golang.org/laws-of-reflection 表示

 > 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方法的访问,
里面的值则包含有关该值的所有类型信息。



$
$ b


就我们的例子而言,适用于Stringer持有类型Binary
列出了用于满足Stringer的方法,它只是字符串:
Binary的其他方法(Get)没有出现在可用的表达式中。




感觉就像这两个人在对立面。根据第二篇文章,第一次摘录中的变量r应该是(tty,io.Reader),因为这是r的静态类型。相反,文章说* os.File是tty的类型。如果第二个例子是正确的,那么第一个例子中的图应该有所有由二进制类型实现的方法。



我哪里错了?

解决方案

这两篇文章解释了两种截然不同粒度级别的类似概念。正如沃尔克所说,反思法则是当你通过反思来检查对象时实际发生的事情的一个基本概述。你的第二篇文章正在研究一个接口的动态调度属性(它也可以通过反射来解析)以及运行时如何在运行时解析它们。


根据第二篇文章,第一次摘录中的变量r应该是(tty,io.Reader)


基于这种理解,在运行时将接口想象成一个包装对象。它存在于提供有关另一个对象(第二篇文章中的 itable )的信息以知道在包装对象布局中跳转到哪里(实现可能会因版本而有所不同)原则对于大多数语言基本上是相同的)。



这就是为什么在上调用 Read r 工作。首先它会检查 itable 并跳转到 os.File 类型。如果这是一个界面,你会看到另一个解除引用和分派(这在II中并不适用IIRC)。



RE:反思 - 通过(value,type) pair(通过 reflect.ValueOf reflect.TypeOf 方法)。


I'm reading through two articles right now and am a little confused.

This article - 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 contains, schematically, the (value, type) pair, (tty, *os.File). Notice that the type *os.File implements methods other than Read; even though the interface value provides access only to the Read method, the value inside carries all the type information about that value.

This other article, says

In terms of our example, the itable for Stringer holding type Binary lists the methods used to satisfy Stringer, which is just String: Binary's other methods (Get) make no appearance in the itable.

It feels like these two are in opposition. According to the second article, the variable r in the first extract should be (tty, io.Reader), as that is the static type of r. Instead, the article says that *os.File is the type of tty. If the second example were right, then the diagram in the first example should have all of the methods implemented by the Binary type.

Where am I going wrong?

解决方案

The two articles are explaining a similar concept at two very different levels of granularity. As Volker said, "Laws of Reflection" is a basic overview of what is actually happening when you examine objects via reflection. Your second article is examining the dynamic dispatch properties of an interface (which, can be resolved via reflection as well) and how the runtime resolves them at runtime.

According to the second article, the variable r in the first extract should be (tty, io.Reader)

Given that understanding, think of an interface at runtime as a "wrapper object". It exists to provide information about another object (the itable from your second article) to know where to jump to in the wrapped objects layout (implementation may differ between versions .. but the principle is basically the same for most languages).

This is why calling Read on r works .. first it will check the itable and jump to the function that is laid out for the os.File type. If that was an interface .. you would be looking at another dereference and dispatch (which IIRC isn't applicable at all in Go).

RE: Reflection - you're getting an easily digestible representation of this, in the form of a (value, type) pair (via the reflect.ValueOf and reflect.TypeOf methods).

这篇关于Go中的接口如何表示?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆