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

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 12.9 Json 數據格式 數據結構要在網絡中傳輸或保存到文件,就必須對其編碼和解碼;目前存在很多編碼格式:JSON,XML,gob,Google 緩沖協議等等。Go 語言支持所有這些編碼格式;在后面的章節,我們將討論前三種格式。 結構可能包含二進制數據,如果將其作為文本打印,那么可讀性是很差的。另外結構內部可能包含匿名字段,而不清楚數據的用意。 通過把數據轉換成純文本,使用命名的字段來標注,讓其具有可讀性。這樣的數據格式可以通過網絡傳輸,而且是與平臺無關的,任何類型的應用都能夠讀取和輸出,不與操作系統和編程語言的類型相關。 下面是一些術語說明: * 數據結構 --> 指定格式 =?`序列化`?或?`編碼`(傳輸之前) * 指定格式 --> 數據格式 =?`反序列化`?或?`解碼`(傳輸之后) 序列化是在內存中把數據轉換成指定格式(data -> string),反之亦然(string -> data structure) 編碼也是一樣的,只是輸出一個數據流(實現了 io.Writer 接口);解碼是從一個數據流(實現了 io.Reader)輸出到一個數據結構。 我們都比較熟悉 XML 格式(參閱?[12.10](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/12.9.md));但有些時候 JSON(JavaScript Object Notation,參閱?[http://json.org](http://json.org/))被作為首選,主要是由于其格式上非常簡潔。通常 JSON 被用于 web 后端和瀏覽器之間的通訊,但是在其它場景也同樣的有用。 這是一個簡短的 JSON 片段: ~~~ { "Person": { "FirstName": "Laura", "LastName": "Lynn" } } ~~~ 盡管 XML 被廣泛的應用,但是 JSON 更加簡潔、輕量(占用更少的內存、磁盤及網絡帶寬)和更好的可讀性,這也說明它越來越受歡迎。 Go 語言的 json 包可以讓你在程序中方便的讀取和寫入 JSON 數據。 我們將在下面的例子里使用 json 包,并使用練習 10.1 vcard.go 中一個簡化版本的 Address 和 VCard 結構(為了簡單起見,我們忽略了很多錯誤處理,不過在實際應用中你必須要合理的處理這些錯誤,參閱 13 章) 示例 12.16?[json.go](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/examples/chapter_12/json.go): ~~~ // json.go.go package main import ( "encoding/json" "fmt" "log" "os" ) type Address struct { Type string City string Country string } type VCard struct { FirstName string LastName string Addresses []*Address Remark string } func main() { pa := &Address{"private", "Aartselaar", "Belgium"} wa := &Address{"work", "Boom", "Belgium"} vc := VCard{"Jan", "Kersschot", []*Address{pa, wa}, "none"} // fmt.Printf("%v: \n", vc) // {Jan Kersschot [0x126d2b80 0x126d2be0] none}: // JSON format: js, _ := json.Marshal(vc) fmt.Printf("JSON format: %s", js) // using an encoder: file, _ := os.OpenFile("vcard.json", os.O_CREATE|os.O_WRONLY, 0) defer file.Close() enc := json.NewEncoder(file) err := enc.Encode(vc) if err != nil { log.Println("Error in encoding json") } } ~~~ `json.Marshal()`?的函數簽名是?`func Marshal(v interface{}) ([]byte, error)`,下面是數據編碼后的 JSON 文本(實際上是一個 []bytes): ~~~ { "FirstName": "Jan", "LastName": "Kersschot", "Addresses": [{ "Type": "private", "City": "Aartselaar", "Country": "Belgium" }, { "Type": "work", "City": "Boom", "Country": "Belgium" }], "Remark": "none" } ~~~ 出于安全考慮,在 web 應用中最好使用?`json.MarshalforHTML()`?函數,其對數據執行HTML轉碼,所以文本可以被安全地嵌在 HTML?`<script>`?標簽中。 JSON 與 Go 類型對應如下: * bool 對應 JSON 的 booleans * float64 對應 JSON 的 numbers * string 對應 JSON 的 strings * nil 對應 JSON 的 null 不是所有的數據都可以編碼為 JSON 類型:只有驗證通過的數據結構才能被編碼: * JSON 對象只支持字符串類型的 key;要編碼一個 Go map 類型,map 必須是 map[string]T(T是?`json`?包中支持的任何類型) * Channel,復雜類型和函數類型不能被編碼 * 不支持循環數據結構;它將引起序列化進入一個無限循環 * 指針可以被編碼,實際上是對指針指向的值進行編碼(或者指針是 nil) ### [](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/12.9.md#反序列化)反序列化: `UnMarshal()`?的函數簽名是?`func Unmarshal(data []byte, v interface{}) error`?把 JSON 解碼為數據結構。 我們首先創建一個結構 Message 用來保存解碼的數據:`var m Message`?并調用?`Unmarshal()`,解析 []byte 中的 JSON 數據并將結果存入指針 m 指向的值 雖然反射能夠讓 JSON 字段去嘗試匹配目標結構字段;但是只有真正匹配上的字段才會填充數據。字段沒有匹配不會報錯,而是直接忽略掉。 (練習 15.2b twitter_status_json.go 中用到了 UnMarshal) ### [](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/12.9.md#解碼任意的數據)解碼任意的數據: json 包使用?`map[string]interface{}`?和?`[]interface{}`?儲存任意的 JSON 對象和數組;其可以被反序列化為任何的 JSON blob 存儲到接口值中。 來看這個 JSON 數據,被存儲在變量 b 中: ~~~ b == []byte({"Name": "Wednesday", "Age": 6, "Parents": ["Gomez", "Morticia"]}) ~~~ 不用理解這個數據的結構,我們可以直接使用 Unmarshal 把這個數據編碼并保存在接口值中: ~~~ var f interface{} err := json.Unmarshal(b, &f) ~~~ f 指向的值是一個 map,key 是一個字符串,value 是自身存儲作為空接口類型的值: ~~~ map[string]interface{} { "Name": "Wednesday", "Age": 6, "Parents": []interface{} { "Gomez", "Morticia", }, } ~~~ 要訪問這個數據,我們可以使用類型斷言 ~~~ m := f.(map[string]interface{}) ~~~ 我們可以通過 for range 語法和 type switch 來訪問其實際類型: ~~~ 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 []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") } } ~~~ 通過這種方式,你可以處理未知的 JSON 數據,同時可以確保類型安全。 ### [](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/12.9.md#解碼數據到結構)解碼數據到結構: 如果我們事先知道 JSON 數據,我們可以定義一個適當的結構并對 JSON 數據反序列化。下面的例子中,我們將定義: ~~~ type FamilyMember struct { Name string Age int Parents []string } ~~~ 并對其反序列化: ~~~ var m FamilyMember err := json.Unmarshal(b, &m) ~~~ 程序實際上是分配了一個新的切片。這是一個典型的反序列化引用類型(指針、切片和 map)的例子。 ### [](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/12.9.md#編碼和解碼流)編碼和解碼流 json 包提供 Decoder 和 Encoder 類型來支持常用 JSON 數據流讀寫。NewDecoder 和 NewEncoder 函數分別封裝了 io.Reader 和 io.Writer 接口。 ~~~ func NewDecoder(r io.Reader) *Decoder func NewEncoder(w io.Writer) *Encoder ~~~ 要想把 JSON 直接寫入文件,可以使用 json.NewEncoder 初始化文件(或者任何實現 io.Writer 的類型),并調用 Encode();反過來與其對應的是使用 json.Decoder 和 Decode() 函數: ~~~ func NewDecoder(r io.Reader) *Decoder func (dec *Decoder) Decode(v interface{}) error ~~~ 來看下接口是如何對實現進行抽象的:數據結構可以是任何類型,只要其實現了某種接口,目標或源數據要能夠被編碼就必須實現 io.Writer 或 io.Reader 接口。由于 Go 語言中到處都實現了 Reader 和 Writer,因此 Encoder 和 Decoder 可被應用的場景非常廣泛,例如讀取或寫入 HTTP 連接、websockets 或文件。
                  <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>

                              哎呀哎呀视频在线观看