如何获取接口的指针

How to get a pointer of an interface

这很难解释,但我如何才能获得实现某个接口的东西的指针?


考虑以下代码:

package main

import (
    "fmt"
    "unsafe"
)

type Interface interface {
    Example()
}

type StructThatImplementsInterface struct {
}

func (i *StructThatImplementsInterface) Example() {
}

type StructThatHasInterface struct {
    i Interface
}


func main() {
    sameInterface := &StructThatImplementsInterface{}

    struct1 := StructThatHasInterface{i: sameInterface}
    struct2 := StructThatHasInterface{i: sameInterface}

    TheProblemIsHere(&struct1)
    TheProblemIsHere(&struct2)

}

func TheProblemIsHere(s *StructThatHasInterface) {
    fmt.Printf("Pointer by Printf: %p \n", s.i)
    fmt.Printf("Pointer by Usafe: %v \n", unsafe.Pointer(&s.i))
}

https://play.golang.org/p/HoC5_BBeswA


结果将是:

Pointer by Printf: 0x40c138 
Pointer by Usafe: 0x40c140 
Pointer by Printf: 0x40c138 
Pointer by Usafe: 0x40c148 

请注意 Printf 获得相同的值(因为两个 StructThatHasInterface 使用相同的 sameInterface)。但是,unsafe.Pointer() returns 个不同的值。

如何在不使用 fmtreflect 的情况下获得与 Printf 相同的结果?

在当前版本的 Go 中,接口值是两个字长。具体值或指向具体值的指针存储在第二个字中。使用以下代码将第二个单词作为 uintptr:

  u := (*[2]uintptr)(unsafe.Pointer(&s.i))[1]

此代码不安全,不保证将来有效。

支持的指针获取方式为:

  u := reflect.ValueOf(s.i).Pointer()