使用反射附加到结构中的切片字段

时间:2017-10-21 13:20:42

标签: go reflection

我的request.form看起来像这样:

struct

我有一个如下所示的环境变量,我使用反射来根据键填充结构。

type guitaristT struct {
    Surname  string   `required=true`
    Year     int64    `required=false`
    American bool     // example of missing tag
    Rating   float32  `required=true`
    Styles   []string `required=true,minsize=1`
}

我可以使用反射设置jimiEnvvar :="surname=Hendrix|year=1942|american=true|rating=9.99 |styles=blues|styles=rock|styles=psychedelic" 字段,但我仍然坚持如何附加到string, int64, bool and float32字段样式。例如,根据上述slice,我希望字段jimiEnvvar的值为jimi.Styles

我有以下(简化)代码:

["blues","rock", "psychedelic"]

修改

第二部分(我解决了)正在填充结构中的地图。例如:

result := guitaristT{}
// result.Styles = make([]string, 10) // XXX causes 10 empty strings at start
result.Styles = make([]string, 0)     // EDIT: Alessandro's solution
...
v := reflect.ValueOf(&result).Elem()
...
field := v.FieldByName(key) // eg key = "styles"
...
switch field.Kind() {

case reflect.Slice:
     // this is where I get stuck
     //
     // reflect.Append() has signature:
     //   func Append(s Value, x ...Value) Value

     // so I convert my value to a reflect.Value
     stringValue := reflect.ValueOf(value) // eg value = "blues"

     // field = reflect.Append(field, stringValue)  // XXX doesn't append
     field.Set(reflect.Append(field, stringValue))  // EDIT: Alessandro's solution

jimiEnvvar的样子:

type guitaristT struct {
    ...
    Styles   []string `required=true,minsize=1`
    Cities   map[string]int
}

我这样写道:

jimiEnvvar += "|cities=New York^17|cities=Los Angeles^14"
    case reflect.Map:
        fmt.Println("keyAsString", keyAsString, "is Map, has value:", valueAsString)
        mapKV := strings.Split(valueAsString, "^")
        if len(mapKV) != 2 {
            log.Fatalln("malformed map key/value:", mapKV)
        }
        mapK := mapKV[0]
        mapV := mapKV[1]
        thisMap := fieldAsValue.Interface().(map[string]int)
        thisMap[mapK] = atoi(mapV)
        thisMapAsValue := reflect.ValueOf(thisMap)
        fieldAsValue.Set(thisMapAsValue)

如果您对此感兴趣,则完整代码位于https://github.com/soniah/reflect/blob/master/structs.go。代码只是我写的一些笔记/练习。

EDIT2:

"进入实践" (Butcher和Farina)详细解释了反射,结构和标签。

1 个答案:

答案 0 :(得分:1)

你离我太远了。只需替换为

*** Error: cannot access argument file:
print 1 + 2
--== Red 0.6.3 ==-- 

你完成了。另外,请确保使用

初始化切片
field.Set(reflect.Append(field, stringValue)) 

或者您最终会在result.Styles = make([]string, 0) 数组的顶部放置10个空白字符串。

希望这对您的项目有所帮助并祝您好运。