如何获得interface {}参数以指向其他内容?

How can I make the following work and make the output "Result is: [Value from GetFromMemory]."?

Unfortunately I cannot change the method signatures of GetItem and Get.

http://play.golang.org/p/R5me3Q3y4W

package main

import "fmt"

type Key string

type Item struct {
    Key   Key
    Value string
}

func GetItem(key Key) interface{} {
    return &Item{key, "Value from GetFromMemory"}
}

// How can I make item point to the one created in GetItem?
func Get(key Key, item interface{}) {
    item = GetItem(key)
}

func main() {
    var item Item
    Get("Key1", &item)

    // This should print "Result is: [Value from GetFromMemory]."
    fmt.Printf("Result is: [%s].", item.Value)
}

As you're dealing with interface{} values you either need type assertions or reflection.

If you know which types you will deal with, type assertions are probably the way to go (Code on play):

func GetItem(key Key) interface{} {
    return &Item{key, "Value from GetFromMemory"}
}

func Get(key Key, item interface{}) {
    switch v := item.(type) {
        case **Item:
            *v = GetItem(key).(*Item)
    }
}

// Usage:
var item *Item
Get("Key1", &item)

The code in Get is laid out so that you can easily add more conditions for several more types. The type switch checks the underlying type of item. In this case it is a pointer to a pointer to an Item (it was *Item in main, then we gave Get the address of &item, making it a **Item).

In the section that matches when the type matches, we can then call GetItem, assert that the resulted object is of type *Item and copy it to *v.

Note that I changed the item variable to *Item as you're producing a pointer value in GetItem, so it makes more sense to get the pointer instead of a copy of an Item object.

Also note that you need to check the result of type assertions like the one used to retrieve the value from GetItem. If you don't and the type does not match, say, *Item, your code will blow up with a runtime panic.

Checked type assertions:

v, ok := someInterfaceValue.(SomeType)
// ok will be true if the assertion succeeded

For the sake of completeness, you can solve your problem with reflection as well. Define Get as follows (Example on play):

func Get(key Key, item interface{}) {
    itemp := reflect.ValueOf(item).Elem()
    itemp.Set(reflect.ValueOf(GetItem(key)))
}

What happens is that at first the reflected value of item (type **Item) is dereferenced, assuming that it is a pointer value, giving us a reflected value with type *Item. Said value is then set with the reflected value of GetItem by using the Set method.

Of course you will need to check whether the kind of item is actually a pointer. Not doing this and passing a non-pointer value to Get will result in panics.