GO :json解析及生成json

1骑素、結(jié)構(gòu)體對(duì)象可生成json字符串炫乓,Marshal()是[]byte,需要string去轉(zhuǎn)換
2献丑、json字符串可以映射到一個(gè)struct末捣,但僅限公共元素(大寫(xiě)開(kāi)頭);也可通用的轉(zhuǎn)換到空接口interfece[]创橄,使用對(duì)應(yīng)轉(zhuǎn)換到需要的內(nèi)容
3箩做、具體說(shuō)明見(jiàn)下面例子

 
package main
 
import (
   "fmt"
   "reflect"
   "encoding/json"
   "strings"
)
 
type Class struct {
   Grade int `json:"grade"` //年級(jí)
   ClassNumber int  `json:"classNumber"` //班級(jí)號(hào)
}
 
type Student struct{
   Name string  //大寫(xiě)開(kāi)頭,可被導(dǎo)出妥畏,沒(méi)有`json:".."`邦邦,導(dǎo)出json的字段名是原本名稱(chēng)
   age int  //小寫(xiě)開(kāi)題,不可被導(dǎo)出
   Hight int `json:"currentHight"` //導(dǎo)出對(duì)應(yīng)json的字段名為currentHight
   Class *Class `class` //指針醉蚁,指向引用對(duì)象圃酵;如果不用指針,只是值復(fù)制
}
 
func doMarshal(){//對(duì)象轉(zhuǎn)json字符串
   nClass:=new(Class)//new只給給特定類(lèi)型分配內(nèi)存馍管,設(shè)置“零”值郭赐,返回其地址(指針)
   fmt.Printf("nClass的類(lèi)型是%s,內(nèi)容是%v\n",reflect.TypeOf(nClass),*nClass)
   nClass.Grade=3
   nClass.ClassNumber=6
   nStudents:=make([]*Student,0)
   //make只用于map,slice和channel确沸,并且不顯示返回指針
   //這個(gè)切片捌锭,存放Student的指針
   nStudent:=Student{"Lily",7,116,nClass}
   jsonBytes,err1:=json.Marshal(nStudent)//解析后的是[]byte
   if err1!=nil{
      fmt.Printf("轉(zhuǎn)json失敗:%v\n",err1)
      return
   }
   fmt.Println("轉(zhuǎn)成的JSON:") //age不會(huì)被導(dǎo)出
   //{"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("轉(zhuǎn)jsonList失斅奚印:%v\n",err2)
      return
   }
   fmt.Println("轉(zhuǎn)成的列表型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字符串轉(zhuǎn)對(duì)象
   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個(gè)參數(shù)必須是指針,否則報(bào)錯(cuò):json: Unmarshal(non-pointer main.Student)
   //因?yàn)楸仨毥馕龅骄唧w的對(duì)象桨菜,所以需傳入對(duì)象引用豁状,而不是值傳遞
   //score在Student中沒(méi)有此字段,所以被忽略了
   if err!=nil{
      fmt.Printf("解析json字符串異常:%s\n",err)
   }
   fmt.Printf("學(xué)生的名稱(chēng)是%v,班級(jí)信息是%v,年齡是%v(私有對(duì)象不能導(dǎo)入倒得,初始為0)\n",student.Name,*student.Class,student.age)
   //學(xué)生的名稱(chēng)是Lily,學(xué)生的班級(jí)信息是{3 6},學(xué)生的年齡是0
   students:=[]*Student{} //定義切片泻红,同make([]*Student,0)
   err=json.Unmarshal([]byte(jsonListStr),&students)
   if err!=nil{
      fmt.Printf("解析json字符串異常:%s\n",err)
   }
   for _,stu:=range students{ //這里stu是指針類(lèi)型,獲取其屬性可以直接用.Name霞掺,也可以解引用后用.Name
      fmt.Printf("列表:學(xué)生的名稱(chēng)是%s,身高是%d,在%d年級(jí)%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字符串異常:%s\n",err)
   }
   c:=-1
   resolve2JosnObj(student1,c)
   /*
   *************解析json*************
   map元素:
   map[Name]的元素: 類(lèi)型是string谊路,值是 Lily
   map[currentHight]的元素: 類(lèi)型float64,值是 116
   map[age]的元素: 類(lèi)型float64菩彬,值是 12
   map[Class]的元素: map元素:
   ---map[classNumber]的元素: 類(lèi)型float64缠劝,值是 6
   ---map[grade]的元素: 類(lèi)型float64潮梯,值是 3
   map[score]的元素: list元素:
   ---第0個(gè)元素: 類(lèi)型float64,值是 98
   ---第1個(gè)元素: 類(lèi)型float64惨恭,值是 100
   ---第2個(gè)元素: 類(lèi)型float64秉馏,值是 95
    */
   fmt.Println("*************解析jsonlist*************")
   var students1 interface{}
   err=json.Unmarshal([]byte(jsonListStr),&students1)
   if err!=nil{
      fmt.Printf("解析jsonlist字符串異常:%s\n",err)
   }
   d:=-1
   resolve2JosnObj(students1,d)
   /*
   *************解析jsonlist*************
   list元素:
   第0個(gè)元素: map元素:
   ---map[Name]的元素: 類(lèi)型是string,值是 Lucy
   ---map[currentHight]的元素: 類(lèi)型float64脱羡,值是 120
   ---map[Class]的元素: map元素:
   ------map[grade]的元素: 類(lèi)型float64萝究,值是 3
   ------map[classNumber]的元素: 類(lèi)型float64,值是 5
   第1個(gè)元素: map元素:
   ---map[Class]的元素: map元素:
   ------map[grade]的元素: 類(lèi)型float64轻黑,值是 3
   ------map[classNumber]的元素: 類(lèi)型float64糊肤,值是 6
   ---map[Name]的元素: 類(lèi)型是string琴昆,值是 Lily
   ---map[currentHight]的元素: 類(lèi)型float64氓鄙,值是 116
    */
}
 
func resolve2JosnObj(objI interface{},c int){
   c=c+1
   switch obj:=objI.(type) { //此處[interface{}].(type) 專(zhuān)門(mén)用于switch的類(lèi)型判斷
   case string:
      fmt.Println("類(lèi)型是string,值是",obj)
   case float64:
      fmt.Println("類(lèi)型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個(gè)元素: ",strings.Repeat("---",c),i)
         resolve2JosnObj(vi,c)
      }
 
   default:
      fmt.Println("無(wú)法判斷類(lèi)型抖拦,類(lèi)型是",reflect.TypeOf(obj),"值是",obj)
 
   }
 
}
 
func main() {
   doMarshal()//對(duì)象轉(zhuǎn)json字符串
   doUnMarshal()
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市舷暮,隨后出現(xiàn)的幾起案子态罪,更是在濱河造成了極大的恐慌,老刑警劉巖下面,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件复颈,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡沥割,警方通過(guò)查閱死者的電腦和手機(jī)耗啦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)机杜,“玉大人帜讲,你說(shuō)我怎么就攤上這事〗忿郑” “怎么了似将?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)蚀苛。 經(jīng)常有香客問(wèn)我在验,道長(zhǎng),這世上最難降的妖魔是什么堵未? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任译红,我火速辦了婚禮,結(jié)果婚禮上兴溜,老公的妹妹穿的比我還像新娘侦厚。我一直安慰自己耻陕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布刨沦。 她就那樣靜靜地躺著诗宣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪想诅。 梳的紋絲不亂的頭發(fā)上召庞,一...
    開(kāi)封第一講書(shū)人閱讀 52,156評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音来破,去河邊找鬼篮灼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛徘禁,可吹牛的內(nèi)容都是我干的诅诱。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼送朱,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼娘荡!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起驶沼,我...
    開(kāi)封第一講書(shū)人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤炮沐,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后回怜,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體大年,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年玉雾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了翔试。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抹凳,死狀恐怖遏餐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赢底,我是刑警寧澤失都,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站幸冻,受9級(jí)特大地震影響粹庞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜洽损,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一庞溜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦流码、人聲如沸又官。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)六敬。三九已至,卻和暖如春驾荣,著一層夾襖步出監(jiān)牢的瞬間外构,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工播掷, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留审编,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓歧匈,卻偏偏與公主長(zhǎng)得像垒酬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子眯亦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容