我正在尝试将参数动态传递给 URL 路由处理函数。我认为可以使用反射包将值的映射从 URL 转换为具有一个恰好是匿名结构的参数的函数。我已经创建了传递给处理程序函数的结构,但它最终成为指向该结构的指针。如果我更改处理程序函数的签名以期望一个指针,那么创建的结构最终会成为一个指向指针的指针,我想。无论如何,这是代码(紧随其后的是恐慌):
链接:http : //play.golang.org/p/vt_wNY1f08
package main
import (
"errors"
"fmt"
"net/http"
"reflect"
"strconv"
"github.com/gorilla/mux"
)
func mapToStruct(obj interface{}, mapping map[string]string) error {
dataStruct := reflect.Indirect(reflect.ValueOf(obj))
if dataStruct.Kind() != reflect.Struct {
return errors.New("expected a pointer to a struct")
}
for key, data := range mapping {
structField := dataStruct.FieldByName(key)
if !structField.CanSet() {
fmt.Println("Can't set")
continue
}
var v interface{}
switch structField.Type().Kind() {
case reflect.Slice:
v = data
case reflect.String:
v = string(data)
case reflect.Bool:
v = string(data) == "1"
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32:
x, err := strconv.Atoi(string(data))
if err != nil {
return errors.New("arg " + key + " as int: " + err.Error())
}
v = x
case reflect.Int64:
x, err := strconv.ParseInt(string(data), 10, 64)
if err != nil {
return errors.New("arg " + key + " as int: " + err.Error())
}
v = x
case reflect.Float32, reflect.Float64:
x, err := strconv.ParseFloat(string(data), 64)
if err != nil {
return errors.New("arg " + key + " as float64: " + err.Error())
}
v = x
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
x, err := strconv.ParseUint(string(data), 10, 64)
if err != nil {
return errors.New("arg " + key + " as int: " + err.Error())
}
慕码人8056858
相关分类