如何获取接口的指针
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 个不同的值。
如何在不使用 fmt
和 reflect
的情况下获得与 Printf
相同的结果?
在当前版本的 Go 中,接口值是两个字长。具体值或指向具体值的指针存储在第二个字中。使用以下代码将第二个单词作为 uintptr
:
u := (*[2]uintptr)(unsafe.Pointer(&s.i))[1]
此代码不安全,不保证将来有效。
支持的指针获取方式为:
u := reflect.ValueOf(s.i).Pointer()
这很难解释,但我如何才能获得实现某个接口的东西的指针?
考虑以下代码:
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 个不同的值。
如何在不使用 fmt
和 reflect
的情况下获得与 Printf
相同的结果?
在当前版本的 Go 中,接口值是两个字长。具体值或指向具体值的指针存储在第二个字中。使用以下代码将第二个单词作为 uintptr
:
u := (*[2]uintptr)(unsafe.Pointer(&s.i))[1]
此代码不安全,不保证将来有效。
支持的指针获取方式为:
u := reflect.ValueOf(s.i).Pointer()