欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go如何實(shí)現(xiàn)json字符串與各類(lèi)struct相互轉(zhuǎn)換

 更新時(shí)間:2022年08月30日 14:29:57   作者:FeelTouch Labs  
這篇文章主要介紹了Go如何實(shí)現(xiàn)json字符串與各類(lèi)struct相互轉(zhuǎn)換,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

json字符串與各類(lèi)struct相互轉(zhuǎn)換

不廢話(huà)了都在代碼中了

 
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()
}

簡(jiǎn)單總結(jié)

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)容

結(jié)構(gòu)體轉(zhuǎn)換為JSON字符串的一個(gè)坑

通過(guò)json.Marshal來(lái)將結(jié)構(gòu)體數(shù)據(jù)轉(zhuǎn)換為json字符串時(shí),需要注意結(jié)構(gòu)體內(nèi)成員變量的首字母大小寫(xiě)的問(wèn)題,很容易會(huì)掉進(jìn)坑里.

來(lái)看一下這個(gè)例子

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("%+v\n", s)
	res, _ := json.Marshal(s)
	fmt.Println(string(res))
}

運(yùn)行輸出如下:

$ go run test_json.go
{Name:xiaomo age:18}
{"Name":"xiaomo"}

可以看到轉(zhuǎn)換的json字符串中只包含了Name字段,age字段被忽略了.這是由于在進(jìn)行json解析時(shí),只會(huì)轉(zhuǎn)換結(jié)構(gòu)體能夠?qū)С龅淖侄?首字母大寫(xiě)),其他字段將會(huì)被忽略.

這個(gè)機(jī)制也有個(gè)好處,可以根據(jù)實(shí)際需要,將想要導(dǎo)出字段的名字首字母大寫(xiě),其他字段首字母小寫(xiě)隱藏起來(lái)即可.

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Go http client 連接池不復(fù)用的問(wèn)題

    Go http client 連接池不復(fù)用的問(wèn)題

    這篇文章主要介紹了Go http client 連接池不復(fù)用的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • golang如何修改json文件內(nèi)容的方法示例

    golang如何修改json文件內(nèi)容的方法示例

    這篇文章主要介紹了golang如何修改json文件內(nèi)容的方法示例,使用一個(gè)例子說(shuō)明golang如何訪問(wèn)和修改json文件,有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • golang指數(shù)運(yùn)算操作

    golang指數(shù)運(yùn)算操作

    這篇文章主要介紹了golang指數(shù)運(yùn)算操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Go開(kāi)源項(xiàng)目分布式唯一ID生成系統(tǒng)

    Go開(kāi)源項(xiàng)目分布式唯一ID生成系統(tǒng)

    這篇文章主要為大家介紹了Go開(kāi)源項(xiàng)目分布式唯一ID生成系統(tǒng)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Go語(yǔ)言聲明一個(gè)多行字符串的變量

    Go語(yǔ)言聲明一個(gè)多行字符串的變量

    這篇文章主要介紹了Go語(yǔ)言聲明一個(gè)多行字符串的變量的方法和示例,非常簡(jiǎn)單實(shí)用,有需要的小伙伴可以參考下。
    2015-04-04
  • 使用Go語(yǔ)言簡(jiǎn)單模擬Python的生成器

    使用Go語(yǔ)言簡(jiǎn)單模擬Python的生成器

    這篇文章主要介紹了使用Go語(yǔ)言簡(jiǎn)單模擬Python的生成器,Python的generator是非??岬墓δ?用Go實(shí)現(xiàn)的代碼也較為簡(jiǎn)潔,需要的朋友可以參考下
    2015-08-08
  • 深入了解Golang中reflect反射的使用

    深入了解Golang中reflect反射的使用

    這篇文章主要介紹了深入了解Golang中reflect反射的使用,Go語(yǔ)言中的反射是一種機(jī)制,可以在運(yùn)行時(shí)動(dòng)態(tài)地獲取類(lèi)型信息和操作對(duì)象,以及調(diào)用對(duì)象的方法和屬性等,需要詳細(xì)了解可以參考下文
    2023-05-05
  • 使用goland調(diào)試遠(yuǎn)程代碼的操作步驟

    使用goland調(diào)試遠(yuǎn)程代碼的操作步驟

    大家都知道如何在goland調(diào)試遠(yuǎn)程代碼嗎?今天小編給大家分享一篇教程幫助大家學(xué)習(xí)goland調(diào)試遠(yuǎn)程代碼的操作步驟,感興趣的朋友跟隨小編一起看看吧
    2021-06-06
  • go實(shí)現(xiàn)grpc四種數(shù)據(jù)流模式

    go實(shí)現(xiàn)grpc四種數(shù)據(jù)流模式

    這篇文章主要為大家介紹了go實(shí)現(xiàn)grpc四種數(shù)據(jù)流模式,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • Golang中g(shù)orm無(wú)法將字段更新為空值

    Golang中g(shù)orm無(wú)法將字段更新為空值

    本文主要介紹了Golang中g(shù)orm無(wú)法將字段更新為空值,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05

最新評(píng)論