【发布时间】:2019-12-15 01:03:04
【问题描述】:
这很难解释,但是我怎样才能得到一个实现了某个接口的 something 的指针呢?
考虑下面的代码:
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() 返回不同的值。
如果可能,我如何在不使用fmt 和reflect 的情况下获得Printf 的相同结果?
【问题讨论】:
-
两个struct值中
i字段的地址是不同的值,因此unsafe.Pointer(&s.i)是不同的值。 .如果您不想假设接口在内存中的表示方式 (reflect.ValueOf(s.i).Pointer()),则可以使用 reflect 包。为什么不想使用反射包? -
@CeriseLimón 我认为存在一种 更简单 的方式,而不是反映和理解
reflect如何获得该值。我看reflect,他们使用(*emptyInterface)(unsafe.Pointer(&i)).word,但我不能让它在reflect之外工作,似乎reflect内部有一些magic。 -
表达式
(*[2]uintptr)(unsafe.Pointer(&s.i))[1]有效,但不能保证它将来会有效。 Value.Pointer 方法是解决此问题的受支持方法。其他解决方案要求您对内存布局做出假设。这对我来说似乎并不容易。 -
@CeriseLimón 你能解释一下它为什么有效吗?请将其发布为答案,然后我可以标记为“正确答案”。 :)
标签: go unsafe-pointers