Golang中如何将URL参数值存储为任意数据类型的最佳实践
Golang中如何将URL参数值存储为任意数据类型的最佳实践 不知道如何在标题中解释,所以我想实现的基本目标是:
我正在创建一个小型的键值存储项目,但希望能够通过URL存储任意数据类型(通过图形界面是否会更简单?)。例如…当你输入 /Dog/Zeus 时,它会将其保存为 Dog: "Zeus"(字符串)…但当我输入 /Cash/1000 时,它会将其保存为 Cash: 1000(整数)。目前,我的代码只是将条目保存为字符串。我需要支持任意数据类型。
完整代码:
package main
import (
"fmt"
"log"
"net/http"
"github.com/gorilla/mux"
)
var data map[string][]string
func main() {
data = map[string][]string{}
r := mux.NewRouter()
r.HandleFunc("/keys", handleDisplay).Methods("GET")
r.HandleFunc("/keys/{key}", handleDisplay).Methods("GET")
r.HandleFunc("/updatekey/{key}/{newkey}", handleUpdate).Methods("PUT")
映射:
var data map[string][]string
处理函数:
r.HandleFunc("/keys", handleDisplay).Methods("GET")
r.HandleFunc("/keys/{key}", handleDisplay).Methods("GET")
r.HandleFunc("/updatekey/{key}/{newkey}", handleUpdate).Methods("PUT")
r.HandleFunc("/update/{key}/{value}/{newvalue}", handleUpdate).Methods("PUT")
r.HandleFunc("/insert/{key}/{value}", handleCreate).Methods("POST")
r.HandleFunc("/delete/{key}", handleDelete).Methods("DELETE")
r.HandleFunc("/delete/{key}/{value}", handleDelete).Methods("DELETE")
显示、创建和更新函数:
func handleDisplay(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
k := params["key"]
if k != "" {
for item := range data {
if item == k {
for _, value := range data[k] {
fmt.Fprintf(w, "KEY: %v: VALUE: %v\n", k, value)
}
}
}
} else {
for item := range data {
for _, value := range data[item] {
fmt.Fprintf(w, "KEY: %v: VALUE: %v\n", item, value)
}
}
}
}
func handleUpdate(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
k := params["key"]
v := params["value"]
nv := params["newvalue"]
nk := params["newkey"]
if v == "" && nv == "" {
if val, ok := data[k]; ok {
data[nk] = val
delete(data, k)
fmt.Fprintf(w, "KEY: %v has been updated with new KEY: %v", k, nk)
} else {
fmt.Fprintf(w, "The KEY: %v doesn't exist", k)
}
} else {
if _, ok := data[k]; ok {
for i := range data[k] {
data[k] = append(data[k][:i], data[k][i+1:]...)
}
data[k] = append(data[k], nv)
fmt.Fprintf(w, "KEY: %v: VALUE: %v has been updated with Value: %v", k, v, nv)
} else {
fmt.Fprintf(w, "KEY: %s doesn't exist", k)
}
}
}
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)
}
更多关于Golang中如何将URL参数值存储为任意数据类型的最佳实践的实战教程也可以访问 https://www.itying.com/category-94-b0.html
我知道这不是最佳实践……但出于测试目的和方便性考虑,我决定根据CRUD功能来命名它们。
更多关于Golang中如何将URL参数值存储为任意数据类型的最佳实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这并不完全是我想要的功能。我需要解析URL中输入的值,判断该值是布尔值、整数还是字符串,然后相应地存储它们。
你好
将它们存储为字符串以外的类型有什么优势吗?在使用GET方法返回时,最终还是要将它们转换成字符串。
如果你需要的话,可以尝试使用 https://golang.org/pkg/strconv/ 这个包,先尝试转换为布尔值,然后是整数、浮点数,如果都不成功就保留为字符串格式。
只是一个观察,在CRUD操作中不需要在路由中使用方法名 😉

RESTful API设计:最佳实践概要
Philipp Hauer’s Blog – 4 Mar 15
设计HTTP和RESTful API的最佳实践。介绍URL结构、HTTP方法、关系处理、分页和版本控制。
我以为可以这样做:https://goplay.space/#2BKtalFyGXl
package main
import (
"fmt"
"strconv"
)
func parseValue(s string) interface{} {
b, err := strconv.ParseBool(s)
if err == nil {
return b
}
i, err := strconv.ParseInt(s, 10, 64)
if err == nil {
return i
}
f, err := strconv.ParseFloat(s, 64)
if err == nil {
return f
}
return s
}
func main() {
v := parseValue("false")
fmt.Printf("%T %#v\n", v, v)
v = parseValue("33")
fmt.Printf("%T %#v\n", v, v)
v = parseValue("3.14")
fmt.Printf("%T %#v\n", v, v)
v = parseValue("hello")
fmt.Printf("%T %#v\n", v, v)
}
在Golang中处理URL参数并存储为任意数据类型,最佳实践是使用interface{}类型来存储值,并在解析时进行类型推断。以下是改进方案:
首先修改数据结构:
var data map[string][]interface{}
然后创建类型推断函数:
func parseValue(valueStr string) interface{} {
// 尝试解析为整数
if intVal, err := strconv.Atoi(valueStr); err == nil {
return intVal
}
// 尝试解析为浮点数
if floatVal, err := strconv.ParseFloat(valueStr, 64); err == nil {
return floatVal
}
// 尝试解析为布尔值
if boolVal, err := strconv.ParseBool(valueStr); err == nil {
return boolVal
}
// 默认为字符串
return valueStr
}
更新处理函数:
func handleCreate(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
k := params["key"]
v := parseValue(params["value"])
data[k] = append(data[k], v)
fmt.Fprintf(w, "KEY: %v: VALUE: %v (%T) was inserted into the key-value store successfully", k, v, v)
}
func handleDisplay(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
k := params["key"]
if k != "" {
if values, exists := data[k]; exists {
for _, value := range values {
fmt.Fprintf(w, "KEY: %v: VALUE: %v (Type: %T)\n", k, value, value)
}
}
} else {
for key, values := range data {
for _, value := range values {
fmt.Fprintf(w, "KEY: %v: VALUE: %v (Type: %T)\n", key, value, value)
}
}
}
}
func handleUpdate(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
k := params["key"]
v := params["value"]
nv := parseValue(params["newvalue"])
nk := params["newkey"]
if v == "" && nv == "" {
if val, ok := data[k]; ok {
data[nk] = val
delete(data, k)
fmt.Fprintf(w, "KEY: %v has been updated with new KEY: %v", k, nk)
} else {
fmt.Fprintf(w, "The KEY: %v doesn't exist", k)
}
} else {
if values, ok := data[k]; ok {
parsedValue := parseValue(v)
for i, existingValue := range values {
if existingValue == parsedValue {
data[k][i] = nv
fmt.Fprintf(w, "KEY: %v: VALUE: %v has been updated with Value: %v (Type: %T)", k, v, nv, nv)
return
}
}
} else {
fmt.Fprintf(w, "KEY: %s doesn't exist", k)
}
}
}
初始化数据结构:
func main() {
data = make(map[string][]interface{})
r := mux.NewRouter()
// 路由注册保持不变
// ...
log.Fatal(http.ListenAndServe(":8080", r))
}
现在系统可以自动识别并存储不同的数据类型:
/insert/Cash/1000会存储为整数 1000/insert/Price/99.99会存储为浮点数 99.99/insert/Active/true会存储为布尔值 true/insert/Dog/Zeus会存储为字符串 “Zeus”
显示时会同时输出值和类型信息,便于调试和使用。

