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 關注
- 152 瀏覽
添加回答
舉報