当前位置:  开发笔记 > 编程语言 > 正文

golang通过反射从接口获取结构

如何解决《golang通过反射从接口获取结构》经验,为你挑选了0个好方法。

原始问题:

我正在尝试进行反序列化,并且在传递接口时如何访问结构有些困惑。

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

}

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)
}

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

我想到了复制我的结构,从而从这里获取可寻址实例的想法:https : //gist.github.com/hvoecking/10772475

所以我想我的问题是,现在有没有一种机制可以访问可寻址/可设置的结构而不必求助于副本?

潜在的问题是采用字符串(实际上是字节数组),并具有一个结构,该结构具有有效地反序列化所需的信息,而不必编写数十个反序列化函数来维护。因此,样本问题中未解决这些样本结构中的标记,但是访问structs标记字段将提供从输入字节填充结构的偏移量。显然我还没走那么远。我在这里感到沮丧的部分原因是,我似乎很努力地努力不走得太远,而且我不觉得自己在此过程中学到了很多东西。

一些其他的剧本编辑让我回过头来:http : //play.golang.org/p/2DbbWLDKPI

推荐阅读
Gbom2402851125
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有