为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕容森 2021-07-02 10:02:03
如何进行以下工作并进行输出"Result is: [Value from GetFromMemory]."?不幸的是我无法改变的方法签名GetItem和Get。http://play.golang.org/p/R5me3Q3y4Wpackage mainimport "fmt"type Key stringtype 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)}
查看完整描述

1 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

当您处理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)

中的代码Get已布局,以便您可以轻松地为更多类型添加更多条件。该类型的开关检查的基础类型的item。在这种情况下,它是一个指向 an 的指针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

为了完整起见,您也可以使用反射来解决您的问题。定义Get如下(播放示例):


func Get(key Key, item interface{}) {

    itemp := reflect.ValueOf(item).Elem()

    itemp.Set(reflect.ValueOf(GetItem(key)))

}

发生的情况是,首先item(type **Item)的反射值被取消引用,假设它是一个指针值,给我们一个 type 的反射值*Item。然后GetItem通过使用该Set方法将所述值设置为的反映值。


当然,您需要检查类型item是否实际上是指针。不这样做并传递非指针值Get将导致恐慌。


查看完整回答
反对 回复 2021-07-05
  • 1 回答
  • 0 关注
  • 333 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信