2 回答
TA贡献1878条经验 获得超4个赞
应用程序必须将字符串解析为可分配给该字段的值。
使用类型开关和值开关查找要解析的类型或种类。
使用strconv 包解析数值和布尔值。使用time 包来解析时间和持续时间。
这是一些示例代码:
v := reflect.ValueOf(&s).Elem()
t := v.Type()
for i := 0; i < t.NumField(); i++ {
sf := t.Field(i)
// Get value from query. Skip if not set.
values, ok := query[strings.ToLower(sf.Name)]
if !ok || len(values) == 0 {
continue
}
// Use type switch for specific types.
switch f := v.Field(i).Addr().Interface().(type) {
case *time.Time:
var err error
*f, err = time.Parse(time.RFC3339, values[0])
if err != nil {
log.Fatal(err)
}
case *time.Duration:
var err error
*f, err = time.ParseDuration(values[0])
if err != nil {
log.Fatal(err)
}
default:
// The specific type was not handled. Fallback
// to using the field kind. This allows us to
// handle all numeric and bool types without knowing
// those types explicitly.
switch sf.Type.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
n, err := strconv.ParseInt(values[0], 10, sf.Type.Bits())
if err != nil {
log.Fatal(err)
}
v.Field(i).SetInt(n)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
n, err := strconv.ParseUint(values[0], 10, sf.Type.Bits())
if err != nil {
log.Fatal(err)
}
v.Field(i).SetUint(n)
case reflect.Float64, reflect.Float32:
n, err := strconv.ParseFloat(values[0], sf.Type.Bits())
if err != nil {
log.Fatal(err)
}
v.Field(i).SetFloat(n)
case reflect.Bool:
b, err := strconv.ParseBool(values[0])
if err != nil {
log.Fatal(err)
}
v.Field(i).SetBool(b)
case reflect.String:
v.Field(i).SetString(values[0])
default:
log.Fatal("unknown type")
}
}
}
首先检查类型,以便将 time.Duration 解析为持续时间而不是整数。
将 log.Fatal 调用替换为适合您的场景的错误处理。
TA贡献1862条经验 获得超7个赞
val := reflect.ValueOf("30")
传入参数的类型("30"在您的示例代码中)是string。它的类型永远不会匹配数字字段的类型。
你必须检查structFieldType,以确定你应该应用什么转换val。
另一种方法可能是向您的结构添加一个特定的方法来填充它的字段:
AssignFields(in url.Values) error
# or
AssignField(name string, value string) error
- 2 回答
- 0 关注
- 126 浏览
添加回答
举报