考虑以下响应 GET '/venues/:id' 的代码:
func venueShow(w http.ResponseWriter, req *http.Request) {
// get ID from params
vars := mux.Vars(req)
id := vars["id"]
// initialise new struct
var venue Venue
// select by id and scan into struct
db.First(&venue, id).Scan(&venue)
// turn it to json
response := structToJSON(&venue)
// write headers and provide response
w.Header().Set("Content-Type", "application/json")
w.Write(response)
}
和:
func structToJSON (s interface{}) (response []byte) {
// turn it into pretty-ish json
response, err := json.MarshalIndent(&s, "", " ")
if err != nil {
return []byte("Venue does not exist")
}
// return the json as the reponse
return response
}
我的 structToJSON 函数采用空接口(interface)作为参数,因为我想将各种不同的结构传递给该函数并让它们作为 JSON 输出。
但是,我觉得它并不安全。如果任何东西满足一个空接口(interface),我可以将我想要的任何东西传递给那个函数,当 json.Marshal 试图做它的业务时,可能会发生各种错误。这(我想)会被编译器捕获而不是在运行时捕获,但是有没有更安全的方法?
我可以为传递给它的每种不同类型的结构/模型复制 structToJSON 方法,但这不是很干。
谢谢
最佳答案
Marshal 函数还将其参数作为 interface{}
接收,因此无法检测您是否在编译时传递了无效的内容,它们都在运行时被捕获。
检查是否将无效类型传递给 Marshal 可以做的一件事是检查错误类型,当您尝试编码(marshal)无效类型时,Marshal 返回一个 UnsupportedTypeError
(如 chan
或 func
),这样您就可以在编码(marshal)处理时检查该错误。
所以你可以尝试这样的事情:
if err != nil {
_, ok := err.(*json.UnsupportedTypeError)
if ok {
return []byte("Tried to Marshal Invalid Type")
} else {
return []byte("Venue does not exist")
}
}
关于json - Go - 将通用结构传递给函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33916050/