创建具有类型接口的地图以通过URL参数接受任意数据类型

时间:2019-01-09 03:53:36

标签: go

我想将URL参数从字符串转换为正确的数据类型,并将其存储在地图中。我相信类型应该是[] interface,以存储多种数据类型的列表。

我正在创建一个键值存储,但是目前,它仅存储字符串。我已经阅读了GOB,将数据转换为字节,但不了解。

我尝试过类型断言,但是,在我的情况下,我认为这不会起作用,因为数据来自默认情况下已经是字符串的URL。如何检测条目是否为字符串,整数,布尔值等?

地图:

var data map[string][]string 
主函数中的

handleFunc调用handleCreate函数

r.HandleFunc("/insert/{key}/{value}", handleCreate).Methods("POST")  

handleFunc函数

func handleCreate(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)

k := params["key"]
v := params["value"]

data[k] = append(data[k], v)
fmt.Fprintf(w, "KEY: %v: VALUE: %v was inserted into the key-value store successfully", k, v)
}

完整代码的链接:

https://github.com/RipRoss/TrainingProjects/blob/master/main.go

预期结果是将URL中给定的值存储为预期的值。例如,/ dog / Zeus将Zeus存储为带有键“ dog”的字符串,/ cash / 1000将存储1000作为类型为int类型的键“ cash”

2 个答案:

答案 0 :(得分:1)

  

我尝试过类型断言,但是,在我的情况下,我认为这不会起作用,因为数据来自默认情况下已经是字符串的URL。如何检测条目是否为字符串,整数,布尔值等?

通常,使事物过分动态化不是一个好主意(使事物的推理变得比需要的复杂得多)。最好定义一个结构,然后将值读入其中。

也就是说,如果我们坚持您的问题的措辞,那么您可以做一些事情:

例如,创建一个通用类型,该类型可以存储值的多个版本以及一个标志,以指示该值是否正确解析为该类型:

type GenericValue struct {
    String string

    Integer int
    IntegerOK bool

    Float float64
    FloatOK bool

    Boolean bool
    BooleanOK bool
}

func ParseGenericValue(v string) GenericValue {
    var result GenericValue
    var err error
    result.String = v
    result.Integer, err = strconv.Atoi(v)
    result.IntegerOK = err == nil
    result.Float, err = strconv.ParseFloat(v, 64)
    result.FloatOK = err == nil
    result.Boolean, err = strconv.ParseBool(v)
    result.BooleanOK = err == nil
    return result
}

所有这些操作是使用strconv包尝试将输入字符串解析为整数/浮点/布尔值,如果解析成功,它将使相应的OK字段失效。例如,如果IntegerOK为true,则表明该字符串解析为整数是成功的。

GenericValue结构仍保留原始输入字符串,因此您可以使用它来检查此值是否为整数并对其进行处理,或者检查它是否为字符串并进行其他处理

var v = ParseGenericValue("2")

if v.IntegerOK {
    // do something with v.Integer
} else {
    // maybe just handle v.String in a different way
}

答案 1 :(得分:0)

查看此程序包,它将URL参数转换为具有预期字段的结构。这当然很有用,当您知道预期的数据类型时。

https://github.com/gorilla/schema

例如

type ServiceInput struct {
  Latitude                 float64  `schema:"latitude,required"` //add validations too
  Longitude                 float64  `schema:"longitude"`
}

...

r := new(ServiceInput)
urlParams := request.URL.Query() //request is http.Request

decoder := schema.NewDecoder()
if err := decoder.Decode(r, urlParams); err != nil {
    return nil, lib.ErrBadRequest{Err: err}
}

现在假设请求为GET /foo/bar?latitude=1.2&longitude=3.4,它将相应地设置结构字段。

如果您对字段的类型一无所知,则必须尝试解析为其他类型并进行检查。