我更愿意解码成一个结构并让json/encoding处理正确类型的工作。
type Input struct {
Title,
Selection string
CostPerDayInCent int64
Description string
User int64
AllowMobileContact,
AllowEmailContact,
IsActive bool
}
由于几个原因,这种方法非常普遍和有用。首先,您可以选择类型。其次,您正在定义一个类型,因此您可以附加函数,我发现它作为一种组织代码并避免将结构作为显式函数参数传递的方法非常方便。第三,您可以将注释附加到结构的字段,进一步调整解组。
最后,对我来说,最重要的是,您正在以 Go 处理数据的方式思考数据。在许多流行的现代语言(如 Python)中,代码和文档通常不会将类型附加到函数,或尝试显式枚举对象的属性。围棋不一样。它消除了固有的语言反射是它如此高效的原因之一。这可以为程序员提供巨大的好处——当您了解所有类型时,您就可以确切地知道事物的行为方式,并且可以准确地确定必须传递您调用的函数的内容。我建议您接受显式类型,并尽可能避免将 json 解码为面向接口的类型。你会知道你在处理什么,你也可以为你的消费者明确地定义它。
https://play.golang.org/p/egaequIT8ET与您的方法形成鲜明对比,您无需费心定义类型 - 但您也没有机会选择它们。
package main
import (
"bytes"
"encoding/json"
"fmt"
)
type Input struct {
Title,
Selection string
CostPerDayInCent int64
Description string
User int64
AllowMobileContact,
AllowEmailContact,
IsActive bool
}
func main() {
var input = `{
"Title": "Example Title",
"Section": "machinery",
"CostPerDayInCent": 34500,
"Description": "A description",
"User": 4,
"AllowMobileContact": true,
"AllowEmailContact": true,
"IsActive": false
}`
// map[string]interface
data := make(map[string]interface{})
if err := json.NewDecoder(bytes.NewBufferString(input)).Decode(&data); err != nil {
panic(err)
}
fmt.Printf("%f %T\n", data["CostPerDayInCent"], data["CostPerDayInCent"])
// structure
obj := new(Input)
if err := json.NewDecoder(bytes.NewBufferString(input)).Decode(obj); err != nil {
panic(err)
}
fmt.Printf("%d %T", obj.CostPerDayInCent, obj.CostPerDayInCent)
}