在go(golang)中,如何将接口指针强制转换为结构指针?
我想使用一些需要指向结构的指针的外部代码。在调用代码时,我有一个接口变量 在创建该变量的指针时,指针的类型是在go(golang)中,如何将接口指针强制转换为结构指针?,go,Go,我想使用一些需要指向结构的指针的外部代码。在调用代码时,我有一个接口变量 在创建该变量的指针时,指针的类型是interface{}*,而我需要它作为结构类型的指针类型 想象一下,TestCanGetStructPointer中的代码不知道Cat类,并且它存在于某个外部包中 我怎样才能做到这一点 下面是一个代码示例: import ( "reflect" "testing" ) type Cat struct { name string } type Someth
interface{}*
,而我需要它作为结构类型的指针类型
想象一下,TestCanGetStructPointer
中的代码不知道Cat类,并且它存在于某个外部包中
我怎样才能做到这一点
下面是一个代码示例:
import (
"reflect"
"testing"
)
type Cat struct {
name string
}
type SomethingGeneric struct {
getSomething func() interface{}
}
func getSomeCat() interface{} {
return Cat{}
}
var somethingForCats = SomethingGeneric{getSomething: getSomeCat}
func TestCanGetStructPointer(t *testing.T) {
interfaceVariable := somethingForCats.getSomething()
pointer := &interfaceVariable
interfaceVarType := reflect.TypeOf(interfaceVariable)
structPointerType := reflect.PtrTo(interfaceVarType)
pointerType := reflect.TypeOf(pointer)
if pointerType != structPointerType {
t.Errorf("Pointer type was %v but expected %v", pointerType, structPointerType)
}
}
测试失败,原因是:
指针类型为*接口{},但应*参数化。Cat
以下内容可能会有所帮助:
@dyoo的示例确实有效,但它依赖于您手动施放
Dog
和Cat
下面是一个复杂/冗长的示例,在某种程度上避免了该约束:
package main
import (
"fmt"
"reflect"
)
type Cat struct {
name string
}
type SomethingGeneric struct {
getSomething func() interface{}
}
func getSomeCat() interface{} {
return Cat{name: "Fuzzy Wuzzy"}
}
var somethingForCats = SomethingGeneric{getSomething: getSomeCat}
func main() {
interfaceVariable := somethingForCats.getSomething()
castVar := reflect.ValueOf(interfaceVariable)
castVar.Convert(castVar.Type())
// If you want a pointer, do this:
fmt.Println(reflect.PtrTo(castVar.Type()))
// The deref'd val
if castVar.Type() != reflect.TypeOf(Cat{}) {
fmt.Printf("Type was %v but expected %v\n", castVar, reflect.TypeOf(&Cat{}))
} else {
fmt.Println(castVar.Field(0))
}
}
我找到了这个线程:
x:=somethingForCats.getSomething()(Cat)&x
除非将返回Cat{}
更改为返回&Cat{}
或返回新(Cat)
,然后只需somethingForCats.getSomething()。(*Cat)
@DaveC呃,可以稍微玩一下,但对性能来说肯定不是很好:@DaveC运行此代码的地方不知道Cat类型,所以它不能直接到该类型。此外,此代码需要用于getSomething()返回的任何类型。它适用于单独包中的代码。您需要将一个指向接口的指针传递到这个外部包中。@OvedD然后编辑您的问题。第一段当前说您有一个接口{}
,需要一个*structType
才能传递到其他地方。类型断言是实现这一点的最简单方法。运行此断言的代码没有访问Cat或Dog类的权限
package main
import (
"fmt"
"reflect"
)
type Cat struct {
name string
}
type SomethingGeneric struct {
getSomething func() interface{}
}
func getSomeCat() interface{} {
return Cat{name: "Fuzzy Wuzzy"}
}
var somethingForCats = SomethingGeneric{getSomething: getSomeCat}
func main() {
interfaceVariable := somethingForCats.getSomething()
castVar := reflect.ValueOf(interfaceVariable)
castVar.Convert(castVar.Type())
// If you want a pointer, do this:
fmt.Println(reflect.PtrTo(castVar.Type()))
// The deref'd val
if castVar.Type() != reflect.TypeOf(Cat{}) {
fmt.Printf("Type was %v but expected %v\n", castVar, reflect.TypeOf(&Cat{}))
} else {
fmt.Println(castVar.Field(0))
}
}
package main
import (
"fmt"
"reflect"
)
type Cat struct {
name string
}
//
// Return a pointer to the supplied struct via interface{}
//
func to_struct_ptr(obj interface{}) interface{} {
fmt.Println("obj is a", reflect.TypeOf(obj).Name())
// Create a new instance of the underlying type
vp := reflect.New(reflect.TypeOf(obj))
// Should be a *Cat and Cat respectively
fmt.Println("vp is", vp.Type(), " to a ", vp.Elem().Type())
vp.Elem().Set(reflect.ValueOf(obj))
// NOTE: `vp.Elem().Set(reflect.ValueOf(&obj).Elem())` does not work
// Return a `Cat` pointer to obj -- i.e. &obj.(*Cat)
return vp.Interface()
}
//
// Dump out a pointer ...
//
func test_ptr(ptr interface{}) {
v := reflect.ValueOf(ptr)
fmt.Println("ptr is a", v.Type(), "to a", reflect.Indirect(v).Type())
}
func main() {
cat := Cat{name: "Fuzzy Wuzzy"}
// Reports "*main.Cat"
test_ptr(&cat)
// Get a "*Cat" generically via interface{}
sp := to_struct_ptr(cat)
// *should* report "*main.Cat" also
test_ptr(sp)
fmt.Println("sp is",sp)
}