原始问题:
我正在尝试进行反序列化,并且在传递接口时如何访问结构有些困惑。
package main
import (
"fmt"
"reflect"
)
type Robot struct {
Id int
}
func f(i interface{}) {
v := reflect.ValueOf(i).Elem().FieldByName("Id")
fmt.Println("fields: ", reflect.ValueOf(i).Elem().NumField())
ptr := v.Addr().Interface().(*int)
*ptr = 100
}
func main() {
robot := Robot{}
var iface interface{} = robot // if I omit this line and pass in robot this works
f(&iface)
fmt.Println(robot.Id) //I want to get here 100
}
Run Code Online (Sandbox Code Playgroud)
http://play.golang.org/p/y6UN3KZxRB
如果您只是直接传递结构,则play示例会起作用,但是,可以传递实现特定接口的任何内容(在我的示例中,我只是使用空接口)。但是我无法弄清楚如何将其视为底层结构。
更新:
package main
import (
"fmt"
"reflect"
)
type MessageOne struct {
Header string `FixedWidth:0,4`
FieldOne string `FixedWidth:"4,4"`
FieldTwo string `FixedWidth:"8,4"`
}
type MessageTwo struct {
FieldX string `FixedWidth:"X,Y"`
FieldY string `FixedWidth:"X,Y"`
}
var (
messageMap = map[string]interface{}{
"msg1": MessageOne{FieldOne: "testValueUnchanged"},
"msg2": MessageTwo{},
}
)
func deserialize(input string, i interface{}) interface{} {
value := reflect.ValueOf(i)
fmt.Println("1st Value Type: ", value.Kind())
// unswarp ptr
value = value.Elem()
fmt.Println("Unwrapped: ", value.Kind())
value = value.Elem()
fmt.Println("Unwrapped: ", value.Kind())
// Create a copy that I can set?
copyValue := reflect.New(value.Type()).Elem()
fmt.Println("Orig Struct is settable", value.CanSet())
fmt.Println("Orig StructField0 is settable", value.Field(0).CanSet())
fmt.Println("Copy is: ", copyValue.Kind())
fmt.Println("Copy Struct is settable", copyValue.CanSet())
fmt.Println("Copy StructField0 is settable", copyValue.Field(0).CanSet())
fmt.Println("Orig struct type is: ", value.Type())
fmt.Println("Copy struct type is: ", copyValue.Type())
copyValue.Field(1).SetString("testValueChanged")
return copyValue.Interface()
}
func GetMessageFromInput(input string) interface{} {
selector := input[0:4]
fmt.Println(selector)
field := messageMap[selector]
return deserialize(input, &field)
}
func main() {
val := messageMap["msg1"]
serializedData := "msg1.012345678"
deserializedVal := GetMessageFromInput(serializedData)
//msg1 := deserializedVal.(MessageOne)
fmt.Printf("Orig: %+v \nReceived: %+v", val, deserializedVal)
}
Run Code Online (Sandbox Code Playgroud)
http://play.golang.org/p/Cj9oPPGSLM
我想到了复制我的结构,从而从这里获取可寻址实例的想法:https : //gist.github.com/hvoecking/10772475
所以我想我的问题是,现在有没有一种机制可以访问可寻址/可设置的结构而不必求助于副本?
潜在的问题是采用字符串(实际上是字节数组),并具有一个结构,该结构具有有效地反序列化所需的信息,而不必编写数十个反序列化函数来维护。因此,样本问题中未解决这些样本结构中的标记,但是访问structs标记字段将提供从输入字节填充结构的偏移量。显然我还没走那么远。我在这里感到沮丧的部分原因是,我似乎很努力地努力不走得太远,而且我不觉得自己在此过程中学到了很多东西。
一些其他的剧本编辑让我回过头来:http : //play.golang.org/p/2DbbWLDKPI
您不想传递指向接口的指针,而是想传递指向结构本身的指针。
robot := &Robot{}
f(robot)
Run Code Online (Sandbox Code Playgroud)
http://play.golang.org/p/owv-Y4dnkl
当您分配robot给时iface,您就创建了该值的副本robot。没有办法获得robotfrom的引用iface。
当您传入 时f(&iface),调用reflect.ValueOf(i).Elem()只是返回内部iface值,而不是Robot结构体值。
| 归档时间: |
|
| 查看次数: |
12640 次 |
| 最近记录: |