<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                JSON(Javascript Object Notation)是一種輕量級的數據交換語言,以文字為基礎,具有自我描述性且易于讓人閱讀。盡管JSON是Javascript的一個子集,但JSON是獨立于語言的文本格式,并且采用了類似于C語言家族的一些習慣。JSON與XML最大的不同在于XML是一個完整的標記語言,而JSON不是。JSON由于比XML更小、更快,更易解析,以及瀏覽器的內建快速解析支持,使得其更適用于網絡數據傳輸領域。目前我們看到很多的開放平臺,基本上都是采用了JSON作為他們的數據交互的接口。既然JSON在Web開發中如此重要,那么Go語言對JSON支持的怎么樣呢?Go語言的標準庫已經非常好的支持了JSON,可以很容易的對JSON數據進行編、解碼的工作。 前一小節的運維的例子用json來表示,結果描述如下: ~~~ {"servers":[{"serverName":"Shanghai_VPN","serverIP":"127.0.0.1"},{"serverName":"Beijing_VPN","serverIP":"127.0.0.2"}]} ~~~ 本小節余下的內容將以此JSON數據為基礎,來介紹go語言的json包對JSON數據的編、解碼。 ## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/07.2.md#解析json)解析JSON ### [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/07.2.md#解析到結構體)解析到結構體 假如有了上面的JSON串,那么我們如何來解析這個JSON串呢?Go的JSON包中有如下函數 ~~~ func Unmarshal(data []byte, v interface{}) error ~~~ 通過這個函數我們就可以實現解析的目的,詳細的解析例子請看如下代碼: ~~~ package main import ( "encoding/json" "fmt" ) type Server struct { ServerName string ServerIP string } type Serverslice struct { Servers []Server } func main() { var s Serverslice str := `{"servers":[{"serverName":"Shanghai_VPN","serverIP":"127.0.0.1"},{"serverName":"Beijing_VPN","serverIP":"127.0.0.2"}]}` json.Unmarshal([]byte(str), &s) fmt.Println(s) } ~~~ 在上面的示例代碼中,我們首先定義了與json數據對應的結構體,數組對應slice,字段名對應JSON里面的KEY,在解析的時候,如何將json數據與struct字段相匹配呢?例如JSON的key是`Foo`,那么怎么找對應的字段呢? * 首先查找tag含有`Foo`的可導出的struct字段(首字母大寫) * 其次查找字段名是`Foo`的導出字段 * 最后查找類似`FOO`或者`FoO`這樣的除了首字母之外其他大小寫不敏感的導出字段 聰明的你一定注意到了這一點:能夠被賦值的字段必須是可導出字段(即首字母大寫)。同時JSON解析的時候只會解析能找得到的字段,找不到的字段會被忽略,這樣的一個好處是:當你接收到一個很大的JSON數據結構而你卻只想獲取其中的部分數據的時候,你只需將你想要的數據對應的字段名大寫,即可輕松解決這個問題。 ### [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/07.2.md#解析到interface)解析到interface 上面那種解析方式是在我們知曉被解析的JSON數據的結構的前提下采取的方案,如果我們不知道被解析的數據的格式,又應該如何來解析呢? 我們知道interface{}可以用來存儲任意數據類型的對象,這種數據結構正好用于存儲解析的未知結構的json數據的結果。JSON包中采用map[string]interface{}和[]interface{}結構來存儲任意的JSON對象和數組。Go類型和JSON類型的對應關系如下: * bool 代表 JSON booleans, * float64 代表 JSON numbers, * string 代表 JSON strings, * nil 代表 JSON null. 現在我們假設有如下的JSON數據 ~~~ b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`) ~~~ 如果在我們不知道他的結構的情況下,我們把他解析到interface{}里面 ~~~ var f interface{} err := json.Unmarshal(b, &f) ~~~ 這個時候f里面存儲了一個map類型,他們的key是string,值存儲在空的interface{}里 ~~~ f = map[string]interface{}{ "Name": "Wednesday", "Age": 6, "Parents": []interface{}{ "Gomez", "Morticia", }, } ~~~ 那么如何來訪問這些數據呢?通過斷言的方式: ~~~ m := f.(map[string]interface{}) ~~~ 通過斷言之后,你就可以通過如下方式來訪問里面的數據了 ~~~ for k, v := range m { switch vv := v.(type) { case string: fmt.Println(k, "is string", vv) case int: fmt.Println(k, "is int", vv) case float64: fmt.Println(k,"is float64",vv) case []interface{}: fmt.Println(k, "is an array:") for i, u := range vv { fmt.Println(i, u) } default: fmt.Println(k, "is of a type I don't know how to handle") } } ~~~ 通過上面的示例可以看到,通過interface{}與type assert的配合,我們就可以解析未知結構的JSON數了。 上面這個是官方提供的解決方案,其實很多時候我們通過類型斷言,操作起來不是很方便,目前bitly公司開源了一個叫做`simplejson`的包,在處理未知結構體的JSON時相當方便,詳細例子如下所示: ~~~ js, err := NewJson([]byte(`{ "test": { "array": [1, "2", 3], "int": 10, "float": 5.150, "bignum": 9223372036854775807, "string": "simplejson", "bool": true } }`)) arr, _ := js.Get("test").Get("array").Array() i, _ := js.Get("test").Get("int").Int() ms := js.Get("test").Get("string").MustString() ~~~ 可以看到,使用這個庫操作JSON比起官方包來說,簡單的多,詳細的請參考如下地址:[https://github.com/bitly/go-simplejson](https://github.com/bitly/go-simplejson) ## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/07.2.md#生成json)生成JSON 我們開發很多應用的時候,最后都是要輸出JSON數據串,那么如何來處理呢?JSON包里面通過`Marshal`函數來處理,函數定義如下: ~~~ func Marshal(v interface{}) ([]byte, error) ~~~ 假設我們還是需要生成上面的服務器列表信息,那么如何來處理呢?請看下面的例子: ~~~ package main import ( "encoding/json" "fmt" ) type Server struct { ServerName string ServerIP string } type Serverslice struct { Servers []Server } func main() { var s Serverslice s.Servers = append(s.Servers, Server{ServerName: "Shanghai_VPN", ServerIP: "127.0.0.1"}) s.Servers = append(s.Servers, Server{ServerName: "Beijing_VPN", ServerIP: "127.0.0.2"}) b, err := json.Marshal(s) if err != nil { fmt.Println("json err:", err) } fmt.Println(string(b)) } ~~~ 輸出如下內容: ~~~ {"Servers":[{"ServerName":"Shanghai_VPN","ServerIP":"127.0.0.1"},{"ServerName":"Beijing_VPN","ServerIP":"127.0.0.2"}]} ~~~ 我們看到上面的輸出字段名的首字母都是大寫的,如果你想用小寫的首字母怎么辦呢?把結構體的字段名改成首字母小寫的?JSON輸出的時候必須注意,只有導出的字段才會被輸出,如果修改字段名,那么就會發現什么都不會輸出,所以必須通過struct tag定義來實現: ~~~ type Server struct { ServerName string `json:"serverName"` ServerIP string `json:"serverIP"` } type Serverslice struct { Servers []Server `json:"servers"` } ~~~ 通過修改上面的結構體定義,輸出的JSON串就和我們最開始定義的JSON串保持一致了。 針對JSON的輸出,我們在定義struct tag的時候需要注意的幾點是: * 字段的tag是`"-"`,那么這個字段不會輸出到JSON * tag中帶有自定義名稱,那么這個自定義名稱會出現在JSON的字段名中,例如上面例子中serverName * tag中如果帶有`"omitempty"`選項,那么如果該字段值為空,就不會輸出到JSON串中 * 如果字段類型是bool, string, int, int64等,而tag中帶有`",string"`選項,那么這個字段在輸出到JSON的時候會把該字段對應的值轉換成JSON字符串 舉例來說: ~~~ type Server struct { // ID 不會導出到JSON中 ID int `json:"-"` // ServerName 的值會進行二次JSON編碼 ServerName string `json:"serverName"` ServerName2 string `json:"serverName2,string"` // 如果 ServerIP 為空,則不輸出到JSON串中 ServerIP string `json:"serverIP,omitempty"` } s := Server { ID: 3, ServerName: `Go "1.0" `, ServerName2: `Go "1.0" `, ServerIP: ``, } b, _ := json.Marshal(s) os.Stdout.Write(b) ~~~ 會輸出以下內容: ~~~ {"serverName":"Go \"1.0\" ","serverName2":"\"Go \\\"1.0\\\" \""} ~~~ Marshal函數只有在轉換成功的時候才會返回數據,在轉換的過程中我們需要注意幾點: * JSON對象只支持string作為key,所以要編碼一個map,那么必須是map[string]T這種類型(T是Go語言中任意的類型) * Channel, complex和function是不能被編碼成JSON的 * 嵌套的數據是不能編碼的,不然會讓JSON編碼進入死循環 * 指針在編碼的時候會輸出指針指向的內容,而空指針會輸出null 本小節,我們介紹了如何使用Go語言的json標準包來編解碼JSON數據,同時也簡要介紹了如何使用第三方包`go-simplejson`來在一些情況下簡化操作,學會并熟練運用它們將對我們接下來的Web開發相當重要。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看