Golang 对接口的反射 vs 指向接口的指针

ego*_*or7 2 go

在 gob 使用示例http://golang.org/src/encoding/gob/example_interface_test.go 中,他们提供了以下论文: Pass pointer to interface so Encode sees (and hence sends) a value of interface type. If we passed p directly it would see the concrete type instead. See the blog post, "The Laws of Reflection" for background.

我已经阅读了两次反射定律,以及一篇相关的 Russ Cox 文章。但是我在那里找不到指针到接口和接口之间的区别。

那么为什么通过指针它看到接口类型的值,而没有指针它看到(对我来说很惊讶)具体类型?

Ain*_*r-G 5

在我看来,相关部分是这样的

继续,我们可以这样做:

var empty interface{}
empty = w
Run Code Online (Sandbox Code Playgroud)

我们的空接口值 empty 将再次包含相同的对,(tty, *os.File)。这很方便:一个空的接口可以保存任何值,并包含我们可能需要的关于该值的所有信息。

(强调)

当您将接口值分配给 type 的值时interface{},新值的“指向数据的指针”部分不指向旧值,而是指向旧值所指向的数据。我们可以用一些unsafe代码来证明:

type iface struct {
    Type, Data unsafe.Pointer
}

var r io.Reader = &bytes.Buffer{}
var i interface{} = r

rr := *(*iface)(unsafe.Pointer(&r))
ii := *(*iface)(unsafe.Pointer(&i))

fmt.Printf("%v\n", ii.Data == rr.Data) // Prints true.
Run Code Online (Sandbox Code Playgroud)

在另一方面,如果我们用一个指针,它指向接口值本身。所以现在reflect实际上可以看到,我们到底在谈论什么接口。例如:

var i2 interface{} = &r
ii2 := *(*iface)(unsafe.Pointer(&i2))
fmt.Printf("%v\n", ii2.Data == unsafe.Pointer(&r)) // Prints true.
Run Code Online (Sandbox Code Playgroud)

游乐场:http : //play.golang.org/p/0ZEMdIFhIj

  • 感谢您指出方向并提供有用的示例。 (2认同)