GO语言练习:构建json 和 解析JSON 实例

本文介绍如何使用Go语言自带的库把对象转换为JSON格式,并在channel中进行传输后,并把JSON格式的信息转换回对象。

1、Go语言的JSON 库

  Go语言自带的JSON转换库为 encoding/json

  1.1)其中把对象转换为JSON的方法(函数)为 json.Marshal(),其函数原型如下

    func Marshal(v  interface{}) ([]byte, error)

    也就是说,这个函数接收任意类型的数据 v,并转换为字节数组类型,返回值就是我们想要的JSON数据和一个错误代码。当转换成功的时候,这个错误代码为nil

    在进行对象转换为 JSON 的过程中,会遵循如下几条规则:

    • 布尔型转换为 JSON 后仍是布尔型 , 如true -> true

    • 浮点型和整数型转换后为JSON里面的常规数字,如 1.23 -> 1.23

    • 字符串将以UTF-8编码转化输出为Unicode字符集的字符串,特殊字符比如<将会被转义为\u003c

    • 数组和切片被转换为JSON 里面的数组,[]byte类会被转换为base64编码后的字符串,slice的零值被转换为null

    • 结构体会转化为JSON对象,并且只有结构体里边以大写字母开头的可被导出的字段才会被转化输出,而这些可导出的字段会作为JSON对象的字符串索引

    • 转化一个map 类型的数据结构时,该数据的类型必须是 map[string]T(T 可以是encoding/json 包支持的任意数据类型)

  1.2)把 JSON 转换回对象的方法(函数)为 json.Unmarshal(),其函数原型如下

    func Unmarshal(data [] byte, v interface{}) error

    这个函数会把传入的 data 作为一个JSON来进行解析,解析后的数据存储在参数 中。这个参数 v 也是任意类型的参数(但一定是一个类型的指针),原因是我们在是以此函数进行JSON 解析的时候,这个函数不知道这个传入参数的具体类型,所以它需要接收所有的类型。

    那么,在进行解析的时候,如果JSON 和 对象的结构不对口会发生什么呢,这就需要解析函数json.Unmarshal()遵循以下规则

    • json.Unmarshal() 函数会根据一个约定的顺序查找目标结构中的字段,如果找到一个即发生匹配。那什么是找到了呢?关于“找到了”又有如下的规则:假设一个JSON对象有个名为"Foo"的索引,要将"Foo"所对应的值填充到目标结构体的目标字段上,json.Unmarshal() 将会遵循如下顺序进行查找匹配

      § 一个包含Foo 标签的字段

      §  一个名为Foo 的字段

      § 一个名为Foo 或者Foo 或者除了首字母其他字母不区分大小写的名为Foo 的字段。 这些字段在类型声明中必须都是以大写字母开头、可被导出的字段。

    注意:如果JSON中的字段在Go目标类型中不存在,json.Unmarshal() 函数在解码过程中会丢弃该字段。

    • 当JSON 的结构是未知的时候,会遵循如下规则:

      § JSON中的布尔值将会转换为Go中的bool类型

      § 数值会被转换为Go中的float64类型

      § 字符串转换后还是string类型

      § JSON数组会转换为[]interface{} 类型

      § JSON对象会转换为map[string]interface{}类型

      § null值会转换为nil

    注意:在Go的标准库encoding/json包中,允许使用map[string]interface{}和[]interface{} 类型的值来分别存放未知结构的JSON对象或数组



2、代码实例

  假设我们有如下一个类(结构体)student 及其一个实例对象st:

type Student struct {
    Name    string
    Age     int
    Guake   bool
    Classes []string
    Price   float32
}

st := &Student {
    "Xiao Ming",
    16,
    true,
    []string{"Math", "English", "Chinese"},
     9.99,
}

  现在我们需要把这个类的一个对象转换为JSON格式,并且传输给远方的朋友,那么我们就可以这么做:

b, err := json.Marshal(st)

  这样就转换好了。是不是很简单!转换回来就更简单了,比如我们有一个新的student对象,就叫stb,那么我们可以这样转换回来:

stb := &Student{}
err = json.Unmarshal([]byte(strData), &stb)

  这样就转换回来了,是不是很简单!

下面是完整代码及运行结果:

$ cat gojson.go

 1 package main
 2
 3 import (
 4     "fmt"
 5     "encoding/json"
 6 )
 7
 8 type Student struct {
 9     Name    string
10     Age        int
11     Guake    bool
12     Classes    []string
13     Price    float32
14 }
15
16 func (s * Student)ShowStu() {
17     fmt.Println("show Student :")
18     fmt.Println("\tName\t:", s.Name)
19     fmt.Println("\tAge\t:", s.Age)
20     fmt.Println("\tGuake\t:", s.Guake)
21     fmt.Println("\tPrice\t:", s.Price)
22     fmt.Printf("\tClasses\t: ")
23     for _, a := range s.Classes {
24         fmt.Printf("%s ", a)
25     }
26     fmt.Println("")
27 }
28
29 func main() {
30     st := &Student {
31         "Xiao Ming",
32         16,
33         true,
34         []string{"Math", "English", "Chinese"},
35         9.99,
36     }
37     fmt.Println("before JSON encoding :")
38     st.ShowStu()
39
40     b, err := json.Marshal(st)
41     if err != nil {
42         fmt.Println("encoding faild")
43     } else {
44         fmt.Println("encoded data : ")
45         fmt.Println(b)
46         fmt.Println(string(b))
47     }
48     ch := make(chan string, 1)
49     go func(c chan string, str string){
50         c <- str
51     }(ch, string(b))
52     strData := <-ch
53     fmt.Println("--------------------------------")
54     stb := &Student{}
55     stb.ShowStu()
56     err = json.Unmarshal([]byte(strData), &stb)
57     if err != nil {
58         fmt.Println("Unmarshal faild")
59     } else {
60         fmt.Println("Unmarshal success")
61         stb.ShowStu()
62     }
63 }

运行结果:

$ go run  gojson.go
before JSON encoding :
show Student :
    Name    : Xiao Ming
    Age    : 16
    Guake    : true
    Price    : 9.99
    Classes    : Math English Chinese
encoded data :
[123 34 78 97 109 101 34 58 34 88 105 97 111 32 77 105 110 103 34 44 34 65 103 101 34 58 49 54 44 34 71 117 97 107 101 34 58 116 114 117 101 44 34 67 108 97 115 115 101 115 34 58 91 34 77 97 116 104 34 44 34 69 110 103 108 105 115 104 34 44 34 67 104 105 110 101 115 101 34 93 44 34 80 114 105 99 101 34 58 57 46 57 57 125]
{"Name":"Xiao Ming","Age":16,"Guake":true,"Classes":["Math","English","Chinese"],"Price":9.99}
--------------------------------
show Student :
    Name    :
    Age    : 0
    Guake    : false
    Price    : 0
    Classes    :
Unmarshal success
show Student :
    Name    : Xiao Ming
    Age    : 16
    Guake    : true
    Price    : 9.99
    Classes    : Math English Chinese

作者:风波

mail : [email protected]

时间: 2024-08-07 21:19:00

GO语言练习:构建json 和 解析JSON 实例的相关文章

jquery JSON的解析方式实例分享

本文以jquery异步获取的数据类型——json对象和字符串为依据,介绍两种方式获取到的结果处理方式. 这里考虑都考虑的是服务器返回的是JSON形式的字符串的形式,对于利用JSONObject等插件封装的JSON对象,与此亦是大同小异,这里不再做说明. 这里首先给出JSON字符串集,字符串集如下:var data="{root:[{name:'1',value:'0'},{name:'6101',value:'西安市'},{name:'6102',value:'铜川市'},{name:'6103

Android原生生成JSON与解析JSON

JSON数据是一种轻量级的数据交换格式,在Android中通常应用于客户端与服务器交互之间的数据传输.像现在在网上有很多解析JSON数据的jar包,但是归根到底用的都是Android原生解析JSON数据的方式,所以掌握Android原生解析JSON数据的方法相当重要. 下面分为生成JSON数据和解析JSON数据,所用的包是org.json (1)生成JSON数据方法: 比如要生成一个这样的json文本 { "phone" : ["12345678", "8

JSON.parse 解析json字符串时,遇换行符报错

今天遇到后台返回的json字符串转对象时报错了,发现有个textarea提交的字段里有换行符. 错误原因:JSON.parse转json字符串时遇到一些特殊字符需要先转义,如图所示 可以用str.replace(/\n/g,"\\\\n")转义,'\\'转成单个'\','\\n'转成'\n',最后转成'\\n'这样就可以用parse转成对象时变为'\n',取出的字符串设置到html文本中\n被解析为换行. ECMA Script注明json字符串中需要转义的字符: 测试: 1.var

JSON序列化 解析JSON

var book = { title : "JavaScript", authors : ["Nickolas . Zakas"], edition : 3, year : 2011 }, jsonText; JSON序列化 //简单序列化 SON.stringify接受3个参数 第一个需要序列化的对象 第二个参数是一个过滤器 可以是数组也可以是一个函数 jsonText = JSON.stringify( book ); //过滤 结果只包含过滤器中的字段 jso

.net使用Newtonsoft.Json.dll解析json过程的几种特殊情况处理

.net用来解析json的库 Newtonsoft.Json.dll 按理说已十分强大,但调用人家的json总有意想不到的情况发生,你没办法要求别人传给你标准的json字符串给你下面是我遇到的几种情况及解决方法:情况1,字段中包含英文引号:{"title": "这个"笑话"一点也不好笑","flag": 0}情况2,{}开头结尾的字段前后有引号:{"content" : "{"微信&qu

swift语言IOS8开发战记24 解析Json

在IOS中使用NSURLConnection实现http通信,NSURLConnection提供了异步和同步两种通信方式,同步请求会造成进程阻塞,通常我们使用异步的方式,不管同步还是异步,建立通信的基本步骤都是一样的: 1,创建NSURL 2,创建Request对象 3,创建NSURLConnection连接 第3步结束后就建立了一个http连接. 这里我们用一个开放的api做例子: http://www.weather.com.cn/adat/sk/101010100.html 这是北京市的当

Newtonsoft.Json.dll解析json的dll文件使用

要解析的json //解析前 //解析前 {"orderlist":[{"backPrice":0,"businessId":93,"businessNotes":"","couponNo":"","createTime":{"date":9,"day":1,"hours":15,&quo

post请求获取json数据 解析json数据

<script> window.onload = function () { var str; // console.log(@ViewBag.ID); $.post("/ServiceBills/ServiceBills/UpdateA", { id: @ViewBag.ID}, function (data) { for (var attr in data) { // console.log(attr);//name,age,gender //console.log(d

【转】c# 解析JSON的几种办法

http://www.cnblogs.com/ambar/archive/2010/07/13/parse-json-via-csharp.html 刚开始只是想找一个转换JSON数组的方法,结果在MSDN翻到一大把. 搜索过程中免不了碰到一大堆名词:WCF => DataContract => DataMember => DataContractJsonSerializer,然后就是不停的引入命名空间. 这一段经历,立即让我就联想到了上面引用的这句存在于某小说里面巫师的话语.静态语言真