指向与保存类型接口的指针 [英] Pointer to interface with saving type
问题描述
解释我的问题的最简单方式是该代码:
var i interface {} //我无法更改它。实际上,这是一个函数,
i = Item {10} //接收接口{},它包含对象(不是指向对象的指针!)
fmt.Printf(%T% (i。(NextValuer).NextVal())//不会编译
i =& i
fmt。 Printf(%T%v \ n,i,i)//这里是指向interface {}(不是Item)的指针
// fmt.Println(i。(NextValuer).NextVal() )// panics
// fmt.Println(i。(* NextValuer).NextVal())//不会编译
但是,如果我尝试设置指向Item的指针,代码有效:
i =& Item {10}
fmt.Printf(%T%v \ n,i,i)
fmt.Println(i。(NextValuer).NextVal())
但是我的函数接收的是对象,而不是指向它的指针。我可以得到它的类型(第一个 fmt.Printf
)。但是当我尝试制作指针时,我收到了指向 interface {}
的指针,而不是我的对象( Item
)。
我可以让这个对象的指针调用 NextVal
?或者可能是其他方式来做到这一点
切勿使用指向接口的指针。如果你需要一个指针来调用带有指针接收器的方法,那么指针就是你必须放入接口{}
。
如果您已在接口{}
中具有值,您想在其中调用带有指针接收器的方法,则需要为该接口创建一个可寻址副本值。
您试图用 i =& i
完成的操作可能是:
item:= i。(Item)
i =& item
这将创建原始 Item
的可寻址副本,然后将指向该副本的指针放入我
。请注意,这永远不会改变原始项目的值
。
如果您不知道类型可以在界面{}
中,您可以使用反映制作该值的副本:
<$ p $ ($ i
v:= reflect.ValueOf(i)
//创建一个指向与我
n:= reflect.New(v.Type())
相同类型的新值的指针//设置新值为i
n。 Elem()。Set(v)
//获取新指针作为接口,并调用NextVal
fmt.Println(NextVal:,n.Interface()。(NextValuer ).NextVal())
//这也可以被赋予另一个接口{}
i = n.Interface()
nv,ok:= i。(NextValuer)
fmt.Printf(我是NextValuer:%t\\\
NextVal:%d\\\
,ok,nv.NextVal())
}
http://play.golang .org / p / gbO9QGz2Tq
The shortest way to explain my problem is that code:
var i interface{} // I can't change it. In fact this is a function,
i = Item{10} // that receives interface{}, that contain object (not pointer to object!)
fmt.Printf("%T %v\n", i, i)
// fmt.Println(i.(NextValuer).NextVal()) // won't compile
i = &i
fmt.Printf("%T %v\n", i, i) // there i is pointer to interface{} (not to Item)
// fmt.Println(i.(NextValuer).NextVal()) // panics
// fmt.Println(i.(*NextValuer).NextVal()) // won't compile
But if I try to set pointer to Item to i, code works:
i = &Item{10}
fmt.Printf("%T %v\n", i, i)
fmt.Println(i.(NextValuer).NextVal())
But my function receives object, not pointer to it. And I can get type of it (first fmt.Printf
). But when I try to make pointer to it, I receive pointer to interface{}
, not to my Object (Item
).
Can I make pointer to this object to call NextVal
? Or may be other ways to do it
Never use a pointer to an interface. If you need a pointer to call a method with a pointer receiver, a pointer is what you must put into the interface{}
.
If you have already have value in an interface{}
where you want to call a method with a pointer receiver, you need to make an addressable copy of that value.
What you're trying to accomplish with i = &i
is probably:
item := i.(Item)
i = &item
This creates an addressable copy of the original Item
, and then puts a pointer to that copy into i
. Note that this can never change the value of the original Item
.
If you don't know the type that can be in the interface{}
, you can make a copy of the value with "reflect":
func nextVal(i interface{}) {
// get the value in i
v := reflect.ValueOf(i)
// create a pointer to a new value of the same type as i
n := reflect.New(v.Type())
// set the new value with the value of i
n.Elem().Set(v)
// Get the new pointer as an interface, and call NextVal
fmt.Println("NextVal:", n.Interface().(NextValuer).NextVal())
// this could also be assigned another interface{}
i = n.Interface()
nv, ok := i.(NextValuer)
fmt.Printf("i is a NextValuer: %t\nNextVal: %d\n", ok, nv.NextVal())
}
http://play.golang.org/p/gbO9QGz2Tq
这篇关于指向与保存类型接口的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!