猿问

指向具有保存类型的接口的指针

解释我的问题的最短方法是代码:


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吗?或者可能是其他方式来做到这一点


慕婉清6462132
浏览 99回答 1
1回答

慕无忌1623718

永远不要使用指向接口的指针。如果您需要一个指针来调用带有指针接收器的方法,则必须将指针放入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())}http://play.golang.org/p/gbO9QGz2Tq
随时随地看视频慕课网APP

相关分类

Go
我要回答