自学探索确实是效率有点低,哈哈。因为我摸索了一下午,一直不出结果,最后才发现是字段首字母大小写问题。
Marshall
用法其实是很简单的,但是我设计了一个例子,字段混合了大小写:
package main
import (
"encoding/json"
"fmt"
)
type Project struct {
Name string
Start string
end string
}
func main() {
var (
s = Project{
Name: "Math",
Start: "2022-1",
end: "2022-2",
}
)
bytes, _ := json.Marshal(s)
fmt.Println(string(bytes))
}
输出结果是只有首字母大写的字段才展示:
{"Name":"Math","Start":"2022-1"}
字段配置
GoLang有个特殊的语法,字段后面可以加上类似java的注解,而json库可以读取这些注解,注解的语法就是字段后面加上多行字符串。比如以下这个例子,我要配置忽略Name字段:
package main
import (
"encoding/json"
"fmt"
)
type Subject struct {
Children []Subject
Name string `json:"-"`
}
func main() {
var (
s = Subject{
Name: "Math",
Children: []Subject{
{Name: "Algebra"},
{Name: "Geometry"},
}}
)
bytes, _ := json.Marshal(s)
fmt.Println(string(bytes))
}
输出的结果中就没有Name这个字段了,下面是输出结果:
{"Children":[{"Children":null},{"Children":null}]}
Unmarshall
将JSON字符串转为对象的过程就是unmarshall,同样对于小写字母开头的不会处理,如以下例子:
package main
import (
"encoding/json"
"fmt"
)
type Subject struct {
Children []Subject
Name string
enName string
}
func main() {
jsonString := `{"Name":"数学","Children":[{"Name":"代数"},{"Name":"几何"}], "enName":"Mathematics"}`
var s Subject
json.Unmarshal([]byte(jsonString), &s)
fmt.Println(s)
}
这个例子和预期的一致,小写字母开头的会被忽略,输出如下:
{[{[] 代数 } {[] 几何 }] 数学 }
小写字母问题
但是小写字母问题是必须要解决的。首先结构体里字段必须要首字母大写,这样符合GoLang的规范。因为JSON是一种网络数据传输格式,所以json数据可能来自其他语言开发的程序,比如JSON数据可能来自java程序,而java的字段名都是首字母小写的,所以需要定义字段的转换。对于这种场景,我们只要在GoLang结构体加上注解就行了:
package main
import (
"encoding/json"
"fmt"
)
type Company struct {
Cpu string `json:"cpu"`
Memory string `json:"memory"`
}
func main() {
jsonStr := `{"cpu":"Intel","memory":"16G"}`
var company Company
json.Unmarshal([]byte(jsonStr), &company)
fmt.Println(company)
}
输出结果成功地将字段小写的原始数据转为了GoLang的首字母大写字段:
{Intel 16G}