设置作为接口{}传递的任何结构的变量

时间:2014-04-18 15:46:21

标签: reflection go go-interface

我想知道在使用interface{}值时如何使用反射设置变量,并且所有类型的结构都可以传递给func F(o interface{})。如何将第一个值(s.A)更改为' hello'?

package main

import (
    "fmt"
    "reflect"
)

type T struct {
    A string
}

func main() {
    F(T{"foo"})
}

func F(o interface{}) {

    t := reflect.ValueOf(&T{"bar"}).Elem()
    s := reflect.ValueOf(&o).Elem()

    // ok
    fmt.Println("struct:   ", t.Field(0).CanSet())

    // panics - how to set s.A?
    fmt.Println("interface:", s.Field(0).CanSet())
}

1 个答案:

答案 0 :(得分:1)

请参阅http://play.golang.org/p/F6M5mfMOTY

当您将参考值&o传递给reflect.ValueOf时,Go会将Elem()解释为interface{},而不是原始类型。如果您不作为参考传递,则会获得您的类型的(不可寻址)实例。我不是百分之百确定这是为什么,但你可以在上面的播放链接中看到行为。

一种方法是创建类型的新可寻址实例,然后迭代s返回的值以设置新实例中的字段,然后将其返回。