gpt4 book ai didi

go - 使用反射附加到结构中的 slice 字段

转载 作者:IT王子 更新时间:2023-10-29 01:44:33 24 4
gpt4 key购买 nike

我有一个看起来像这样的结构:

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 和 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

编辑:

第二部分(我解决了)是在结构中填充映射。例如:

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

jimiEnvvar 的样子:

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)

The final result was:

main.guitaristT{
Surname: "Hendrix",
Year: 1942,
American: true,
Rating: 9.989999771118164,
Styles: {"blues", "rock", "psychedelic"},
Cities: {"London":11, "Bay Area":9, "New York":17, "Los Angeles":14},
}

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


编辑 2:

“Go in Practice”(Butcher 和 Farina)的第 11 章对反射、结构和标签有详细的解释。

最佳答案

你离得不远。只需替换为

field.Set(reflect.Append(field, stringValue)) 

你就完成了。另外,请确保您使用初始化 slice

result.Styles = make([]string, 0)

否则您最终会在 Styles 数组的顶部有 10 个空白字符串。

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

关于go - 使用反射附加到结构中的 slice 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46863664/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com