简体   繁体   中英

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

Have a struct that has fields of type 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:

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

So not sure how to get values into the inner struct 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.

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) . And don't use strings where you don't need them eg rIsOpen sounds like a boolean value to me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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