<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
不廢話了都在程式碼中了
package main import ( "fmt" "reflect" "encoding/json" "strings" ) type Class struct { Grade int `json:"grade"` //年級 ClassNumber int `json:"classNumber"` //班級號 } type Student struct{ Name string //大寫開頭,可被匯出,沒有`json:".."`,匯出json的欄位名是原本名稱 age int //小寫開題,不可被匯出 Hight int `json:"currentHight"` //匯出對應json的欄位名為currentHight Class *Class `class` //指標,指向參照物件;如果不用指標,只是值複製 } func doMarshal(){//物件轉json字串 nClass:=new(Class)//new只給給特定型別分配記憶體,設定「零」值,返回其地址(指標) fmt.Printf("nClass的型別是%s,內容是%vn",reflect.TypeOf(nClass),*nClass) nClass.Grade=3 nClass.ClassNumber=6 nStudents:=make([]*Student,0) //make只用於map,slice和channel,並且不顯示返回指標 //這個切片,存放Student的指標 nStudent:=Student{"Lily",7,116,nClass} jsonBytes,err1:=json.Marshal(nStudent)//解析後的是[]byte if err1!=nil{ fmt.Printf("轉json失敗:%vn",err1) return } fmt.Println("轉成的JSON:") //age不會被匯出 //{"Name":"Lily","currentHight":116,"Class":{"grade":3,"classNumber":6}} fmt.Println(string(jsonBytes)) nStudents=append(nStudents,&Student{"Lilei",8,130,nClass}) nStudents=append(nStudents,&nStudent) josnListBytes,err2:=json.Marshal(nStudents) if err2!=nil{ fmt.Printf("轉jsonList失敗:%vn",err2) return } fmt.Println("轉成的列表型JSON:") fmt.Println(string(josnListBytes)) //[{"Name":"Lilei","currentHight":130,"Class":{"grade":3,"classNumber":6}},{"Name":"Lily","currentHight":116,"Class":{"grade":3,"classNumber":6}}] } func doUnMarshal(){//json字串轉物件 jsonStr:=` { "Name":"Lily", "currentHight":116, "age":12, "Class":{ "grade":3, "classNumber":6 }, "score":[98,100,95] } ` jsonListStr:=`[ { "Name":"Lucy", "currentHight":120, "Class":{ "grade":3, "classNumber":5 } }, { "Name":"Lily", "currentHight":116, "Class":{ "grade":3, "classNumber":6 } } ]` //第一種解析json方式,解析到Struct/[]Struct student:=Student{}//同new(Student) err:=json.Unmarshal([]byte(jsonStr),&student) //Unmarshall第2個引數必須是指標,否則報錯:json: Unmarshal(non-pointer main.Student) //因為必須解析到具體的物件,所以需傳入物件參照,而不是值傳遞 //score在Student中沒有此欄位,所以被忽略了 if err!=nil{ fmt.Printf("解析json字串異常:%sn",err) } fmt.Printf("學生的名稱是%v,班級資訊是%v,年齡是%v(私有物件不能匯入,初始為0)n",student.Name,*student.Class,student.age) //學生的名稱是Lily,學生的班級資訊是{3 6},學生的年齡是0 students:=[]*Student{} //定義切片,同make([]*Student,0) err=json.Unmarshal([]byte(jsonListStr),&students) if err!=nil{ fmt.Printf("解析json字串異常:%sn",err) } for _,stu:=range students{ //這裡stu是指標型別,獲取其屬性可以直接用.Name,也可以解除參照後用.Name fmt.Printf("列表:學生的名稱是%s,身高是%d,在%d年級%d班n",stu.Name,(*stu).Hight,(*stu.Class).Grade,stu.Class.ClassNumber) } //第二種解析到interface{}/[]interface{} fmt.Println("*************解析json*************") var student1 interface{} err=json.Unmarshal([]byte(jsonStr),&student1) if err!=nil{ fmt.Printf("解析json字串異常:%sn",err) } c:=-1 resolve2JosnObj(student1,c) /* *************解析json************* map元素: map[Name]的元素: 型別是string,值是 Lily map[currentHight]的元素: 型別float64,值是 116 map[age]的元素: 型別float64,值是 12 map[Class]的元素: map元素: ---map[classNumber]的元素: 型別float64,值是 6 ---map[grade]的元素: 型別float64,值是 3 map[score]的元素: list元素: ---第0個元素: 型別float64,值是 98 ---第1個元素: 型別float64,值是 100 ---第2個元素: 型別float64,值是 95 */ fmt.Println("*************解析jsonlist*************") var students1 interface{} err=json.Unmarshal([]byte(jsonListStr),&students1) if err!=nil{ fmt.Printf("解析jsonlist字串異常:%sn",err) } d:=-1 resolve2JosnObj(students1,d) /* *************解析jsonlist************* list元素: 第0個元素: map元素: ---map[Name]的元素: 型別是string,值是 Lucy ---map[currentHight]的元素: 型別float64,值是 120 ---map[Class]的元素: map元素: ------map[grade]的元素: 型別float64,值是 3 ------map[classNumber]的元素: 型別float64,值是 5 第1個元素: map元素: ---map[Class]的元素: map元素: ------map[grade]的元素: 型別float64,值是 3 ------map[classNumber]的元素: 型別float64,值是 6 ---map[Name]的元素: 型別是string,值是 Lily ---map[currentHight]的元素: 型別float64,值是 116 */ } func resolve2JosnObj(objI interface{},c int){ c=c+1 switch obj:=objI.(type) { //此處[interface{}].(type) 專門用於switch的型別判斷 case string: fmt.Println("型別是string,值是",obj) case float64: fmt.Println("型別float64,值是",obj) case map[string]interface{}: fmt.Println("map元素:") for k,vi:=range obj{ fmt.Printf("%smap[%s]的元素: ",strings.Repeat("---",c),k) resolve2JosnObj(vi,c) } case []interface{}: fmt.Println("list元素:") for i,vi:=range obj{ fmt.Printf("%s第%d個元素: ",strings.Repeat("---",c),i) resolve2JosnObj(vi,c) } default: fmt.Println("無法判斷型別,型別是",reflect.TypeOf(obj),"值是",obj) } } func main() { doMarshal()//物件轉json字串 doUnMarshal() }
1、結構體物件可生成json字串,Marshal()是[]byte,需要string去轉換
2、json字串可以對映到一個struct,但僅限公共元素(大寫開頭);也可通用的轉換到空介面interfece[],使用對應轉換到需要的內容
通過json.Marshal來將結構體資料轉換為json字串時,需要注意結構體內成員變數的首字母大小寫的問題,很容易會掉進坑裡.
package main import ( "encoding/json" "fmt" ) type Student struct { Name string age int } func main() { var s Student = Student { Name: "xiaomo", age: 18, } fmt.Printf("%+vn", s) res, _ := json.Marshal(s) fmt.Println(string(res)) }
執行輸出如下:
$ go run test_json.go
{Name:xiaomo age:18}
{"Name":"xiaomo"}
可以看到轉換的json字串中只包含了Name欄位,age欄位被忽略了.這是由於在進行json解析時,只會轉換結構體能夠匯出的欄位(首字母大寫),其他欄位將會被忽略.
這個機制也有個好處,可以根據實際需要,將想要匯出欄位的名字首字母大寫,其他欄位首字母小寫隱藏起來即可.
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45