Dan*_*Dan 1 google-app-engine go
如何进行以下工作并进行输出"Result is: [Value from GetFromMemory]."?
不幸的是我无法改变的方法签名GetItem和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)
}
Run Code Online (Sandbox Code Playgroud)
在处理interface{}值时,您需要键入断言或反射.
如果您知道要处理哪些类型,可以选择断言类型(播放代码):
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)
Run Code Online (Sandbox Code Playgroud)
这些代码的Get布局使您可以轻松地为多种类型添加更多条件.该类型的开关检查的基础类型的item.在这种情况下,它是一个指向指针的指针Item(它*Item在main中,然后我们给出Get了地址&item,使其成为a **Item).
在类型匹配时匹配的部分中,我们可以调用GetItem,断言结果对象是类型*Item并将其复制到*v.
请注意,我将item变量更改*Item为您生成指针值GetItem,因此获取指针而不是Item对象的副本更有意义.
另请注意,您需要检查类型断言的结果,例如用于从中检索值的断言GetItem.如果你不这样,并且类型不匹配,比如说*Item,你的代码会因运行时混乱而爆炸.
检查类型断言:
v, ok := someInterfaceValue.(SomeType)
// ok will be true if the assertion succeeded
Run Code Online (Sandbox Code Playgroud)
为了完整起见,您也可以通过反射来解决您的问题.定义Get如下(播放示例):
func Get(key Key, item interface{}) {
itemp := reflect.ValueOf(item).Elem()
itemp.Set(reflect.ValueOf(GetItem(key)))
}
Run Code Online (Sandbox Code Playgroud)
发生的事情是,首先将item(类型**Item)的反射值取消引用,假设它是一个指针值,给我们一个带有类型的反射值*Item.然后GetItem通过使用该Set方法用反射值设置所述值.
当然你需要检查那种item实际上是否是一个指针.不执行此操作并传递非指针值Get将导致恐慌.
| 归档时间: |
|
| 查看次数: |
116 次 |
| 最近记录: |