简体   繁体   English

使用反射来设置结构值的结构值

[英]Use reflect to set values of struct of struct values

I have some code that looks to be working but does nothing in the end: 我有一些看起来可以正常运行的代码,但最终却什么也没做:

http://play.golang.org/p/TfAWWy4-R8 http://play.golang.org/p/TfAWWy4-R8

Have a struct that has fields of type struct. 有一个具有struct类型的字段的结构。 The inner struct has all string fields. 内部结构具有所有字符串字段。

Using reflect in a loop, want to get all struct fields from outer struct. 在循环中使用反射,要从外部结构获取所有结构字段。 Next, populate all string values in inner struct. 接下来,在内部结构中填充所有字符串值。 the example code is getting text from the tags and parsing it on "," to get strings values for inner loop. 示例代码是从标记中获取文本并将其解析为“,”以获取内部循环的字符串值。

This is the main part that should create the inner struct and add the parsed data to the string values. 这是应该创建内部结构并将已解析的数据添加到字符串值的主要部分。

    t := reflect.TypeOf(Alias{})
    alias = reflect.New(t)
    for i := 0; i < alias.Elem().NumField(); i++ {
       p := alias.Elem().Field(i)
       p.SetString(params[i])
    }

It looks like it is working when you look at the output from example, but after printing a value from outer struct it seems to be empty: 当您查看示例的输出时,它似乎正在运行,但是在从外部struct打印值之后,它似乎为空:

fmt.Println("Final01 = ", Attr.Final01.Command) // prints empty string

So not sure how to get values into the inner struct Alias{} 因此,不确定如何将值获取到内部结构Alias {}中

Thanks for any help. 谢谢你的帮助。

Here 's the working program. 是工作程序。 Explanation below. 以下说明。

package main

import "fmt"
import "strings"
import "reflect"

type Alias struct {
    Name         string
    DevicePath   string
    GuiPath      string
    Setpoint     string
    Command      string
    Status       string
    FunctionCmds string
}

type Manifold struct {
    Final01    Alias "Final01,/Gaspanel/Shared/Final01,,,wOpen,rIsOpen,"
    Dump01     Alias "Dump01,/Gaspanel/Shared/Dump01,,,wOpen,rIsOpen,"
    N2Vent01   Alias "N2Vent01,/Gaspanel/Shared/N2Vent01,,,wOpen,rIsOpen,"
    N2Vent201  Alias "N2Vent201,/Gaspanel/Shared/N2Vent201,,,wOpen,rIsOpen,"
    PurgeValve Alias "PurgeValve,/Gaspanel/Shared/Purge01,,,wOpen,rIsOpen,"
}

func MapTagedAliasToChamber(chamber string, struc interface{}) []string {
    attributeStruct := reflect.ValueOf(struc).Elem()
    typeAttributeStruct := attributeStruct.Type()
    attributes := make([]string, attributeStruct.NumField(), attributeStruct.NumField())
    for i := 0; i < attributeStruct.NumField(); i++ {
        alias := attributeStruct.Field(i)
        tag := string(typeAttributeStruct.Field(i).Tag)
        name := typeAttributeStruct.Field(i).Name
        params := strings.Split(tag, ",")
        alias = reflect.New(reflect.TypeOf(Alias{})).Elem()
        for i := 0; i < alias.NumField(); i++ {
            alias.Field(i).SetString(params[i])
        }
        attributeStruct.Field(i).Set(alias)
        fmt.Printf("%d: %s %s = %v\n", i, name, alias.Type(), alias.Interface())
    }

    return attributes
}

func main() {
    Attr := Manifold{}
    MapTagedAliasToChamber("A", &Attr)

    fmt.Println("Final01 = ", Attr.Final01.Command)

}

The problem was on line 38 of your original program, where you created a new reflect.Value named alias representing a value of type *Alias , then filled it with your information but never wrote it back into your Manifold struct. 问题出在原始程序的第38行,您在其中创建了一个新的reflect.Value名为alias的值表示*Alias类型的值,然后用您的信息填充了该值,但从未将其写回到Manifold结构中。

Additionally I suggest that you stick to the standard struct-tag format which can be parsed and used more easily through (reflect.StructTag).Get(key string) . 另外,我建议您坚持使用标准的struct-tag格式,该格式可以通过(reflect.StructTag).Get(key string)进行解析和使用。 And don't use strings where you don't need them eg rIsOpen sounds like a boolean value to me. 并且不要在不需要它们的地方使用字符串,例如rIsOpen对我来说就像一个布尔值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM