golang 读取JSON文件(读书笔记)

lxy15329 · · 3218 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

          JSON(JavaScript Object Notation)是一种比XML更轻量级的数据交换格式,在易于人们阅读和编写的同时,也易于程序解析和生成。尽管JSON是JavaScript的一个子集,但JSON采用完全独立于编程语言的文本格式,且表现为key/value的文本描述形式(与GO语言中的map极为相似),这使它成为较理想的、跨平台的、跨语言的数据交换语言。记得初次接触JSON这种数据形式是在刚工作时,当时在js页面中处理非常方便,印象一直很深刻。后来,学习了一些mongodb,完全处理这种格式的数据。原来,个人很不喜欢像这种键-值对的数据形式,因为总觉得这个底层可能映射起来比较方便,不过,好多情况下确实是少不了这种形式。

    Go语言内建对JSON的支持,使用GO语言内置的encoding/json标准库,开发者可以轻松使用GO程序生成和解析JSON格式的数据。


举个例子:

package main
import (
    "encoding/json"
    "fmt"
)
type Book struct {
    Title       string
    Author      []string
    Publisher   string
    Price       float64
    IsPublished bool
}
func main() {
    b := []byte(`{
    "Title":"go programming language",
    "Author":["john","ada","alice"],
    "Publisher":"qinghua",
    "IsPublished":true,
    "Price":99
  }`)
//先创建一个目标类型的实例对象,用于存放解码后的值
    var book Book
    err := json.Unmarshal(b, &book)
    if err != nil {
        fmt.Println("error in translating,", err.Error())
        return
    }
    fmt.Println(book.Author)
}

Json.Unmarshal()函数会根据一个约定的顺序查找目标结构中的字段,如果找到一个则进行匹配。这些字段在类型声明中必须都是以大写字母开头、可被导出的字段。

但是当JSON数据中的数据结构和GO中的目标类型不匹配时,会怎样呢?如果JSON中的字段在GO目标类型中不存在,json.Unmarshal()函数在解码过程中会丢弃该字段。这个特性让我们可以从一段JSON数据中筛选出指定的值填充到多个GO语言类型中,当然,前提是已知JSON数据的字段结构。这也意味着,目标类型中不可被导出的私有字段(非首字母大写)将不会受到解析转化的影响,

如果要解析一个配置文件,为了使程序端的改动能够灵活,大多数情况下是不知道配置文件中到底是怎样的结构,只是在需要的时候去取就可以了。GO语言支持接口。在go中,接口是一组预定义方法的组合,任何一个类型均可通过实现接口预定义的方法来实现,且无需显示声明,所以没有任何方法的空接口代表任何类型。换句话说,每一个类型其实都至少实现了一个空接口。GO内建这样灵活的类型系统,向我们传达了一个很有价值的信息:空接口是通用类型。如果要解析一段未知结构的JSON,只需向这段JSON数据解码输出到一个空接口即可。在GO的标准库encoding/json包中,允许使用map[string]interface{}和[]interface{}类型的值来分别存放未知结构的JSON对象或数组。

还是刚才的例子,只是将结构体去掉,变成一个未知结构的数据。

package main
import (
    "encoding/json"
    "fmt"
)
func main() {
    b := []byte(`{
    "Title":"go programming language",
    "Author":["john","ada","alice"],
    "Publisher":"qinghua",
    "IsPublished":true,
    "Price":99
  }`)
    //先创建一个目标类型的实例对象,用于存放解码后的值
    var inter interface{}
    err := json.Unmarshal(b, &inter)
    if err != nil {
        fmt.Println("error in translating,", err.Error())
        return
    }
    //要访问解码后的数据结构,需要先判断目标结构是否为预期的数据类型
    book, ok := inter.(map[string]interface{})
    //然后通过for循环一一访问解码后的目标数据
    if ok {
        for k, v := range book {
            switch vt := v.(type) {
            case float64:
                fmt.Println(k, " is float64 ", vt)
            case string:
                fmt.Println(k, " is string ", vt)
            case []interface{}:
                fmt.Println(k, " is an array:")
                for i, iv := range vt {
                    fmt.Println(i, iv)
                }
            default:
                fmt.Println("illegle type")
            }
        }
    }
}

说实话,这样转化确实很繁琐,但也是解析未知结构的JSON数据的方式。

原来试图使用XML来做配置文件,但是,那样的话必须要知道有哪些数据项(Key),而对于灵活的配置文件来说,到底包括哪些是没有办法提前预知的,而各个模块需要哪些数据的时候只需到公共信息中去提取就好了,主程序也不需要知道到底有哪些信息是公用的,它只要负责将消息以键值对的形式保存起来供子程序调用就可以了。



本文来自:CSDN博客

感谢作者:lxy15329

查看原文:golang 读取JSON文件(读书笔记)

入群交流(和以上内容无关):Go中文网 QQ 交流群:798786647 或加微信入微信群:274768166 备注:入群;关注公众号:Go语言中文网

3218 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传