解释我的问题的最简单方法是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
但是如果我尝试将Item设置为i,则代码可以工作:
i = &Item{10}
fmt.Printf("%T %v\n", i, i)
fmt.Println(i.(NextValuer).NextVal())
但我的函数接收对象,而不是指向它的指针。我可以得到它的类型(第一个fmt.Printf
)。但是当我尝试指向它时,我会收到指向interface{}
的指针,而不是指向我的对象(Item
)。
我可以指向此对象来调用NextVal
吗?或者可能是其他方式来做到这一点
答案 0 :(得分:1)
切勿使用指向界面的指针。如果需要一个指针来调用带有指针接收器的方法,那么指针就是你必须放入interface{}
的指针。
如果您要在interface{}
中使用指针接收器调用方法,则需要创建该值的可寻址副本。
您尝试使用i = &i
完成的任务可能是:
item := i.(Item)
i = &item
这将创建原始Item
的可寻址副本,然后将指向该副本的指针放入i
。请注意,这永远不会更改原始Item
的值。
如果您不知道interface{}
中可以包含的类型,则可以使用“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())
}