golang json 包簡單分析

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

首先上代碼:

func main() {b := truea1, _ := json.Marshal(b)a2, _ := Marshal(b)fmt.Println(string(a1))fmt.Println(string(a2))}

輸出:

truetrue

以最簡單的單個bool 類型的序列化為例,我們來搞清楚json 包裡面的調用棧如下:

從入口出發,第一個方法是:

func Marshal(v interface{}) ([]byte, error) {e := &encodeState{}err := e.marshal(v)if err != nil {return nil, err}return e.Bytes(), nil}

這裡沒有什麼特殊,只是為了引出encodeState

// An encodeState encodes JSON into a bytes.Buffer.type encodeState struct {bytes.Buffer // accumulated outputscratch      [64]byte}

這裡的Buffer就是我們所有輸出位元組的Buffer,再繼續往裡面走

func (e *encodeState) marshal(v interface{}) (err error) {defer func() {if r := recover(); r != nil {if _, ok := r.(runtime.Error); ok {panic(r)}if s, ok := r.(string); ok {panic(s)}err = r.(error)}}()e.reflectValue(reflect.ValueOf(v))return nil}

這裡我們看到了反射獲得值,個人認為這裡的命名不太科學,不過無妨,繼續往下走。

func valueEncoder(v reflect.Value) encoderFunc {if !v.IsValid() {return invalidValueEncoder}return typeEncoder(v.Type())}

這裡通過反射的類型,獲得和使用該類型的序列化方法.順便還做了把緩衝。

func typeEncoder(t reflect.Type) encoderFunc {encoderCache.RLock()f := encoderCache.m[t]encoderCache.RUnlock()if f != nil {return f}// To deal with recursive types, populate the map with an// indirect func before we build it. This type waits on the// real func (f) to be ready and then calls it.  This indirect// func is only used for recursive types.encoderCache.Lock()if encoderCache.m == nil {encoderCache.m = make(map[reflect.Type]encoderFunc)}var wg sync.WaitGroupwg.Add(1)encoderCache.m[t] = func(e *encodeState, v reflect.Value, quoted bool) {wg.Wait()f(e, v, quoted)}encoderCache.Unlock()// Compute fields without lock.// Might duplicate effort but won't hold other computations back.f = newTypeEncoder(t, true)wg.Done()encoderCache.Lock()encoderCache.m[t] = fencoderCache.Unlock()return f}

至於具體的Encoder,通過Type很容易找到。

switch t.Kind() {case reflect.Bool:return boolEncodercase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:return intEncodercase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:return uintEncodercase reflect.Float32:return float32Encodercase reflect.Float64:return float64Encodercase reflect.String:return stringEncodercase reflect.Interface:return interfaceEncodercase reflect.Struct:return newStructEncoder(t)case reflect.Map:return newMapEncoder(t)case reflect.Slice:return newSliceEncoder(t)case reflect.Array:return newArrayEncoder(t)case reflect.Ptr:return newPtrEncoder(t)default:return unsupportedTypeEncoder

最終我們這裡的boolEncoder的實現

func boolEncoder(e *encodeState, v reflect.Value, quoted bool) {if quoted {e.WriteByte('"')}if v.Bool() {e.WriteString("true")} else {e.WriteString("false")}if quoted {e.WriteByte('"')}}

當然這個只是一個最簡單的樣本,裡面很多實現的細節可以推敲。這裡只是把這種序列化的方式歸結為類型反射+緩衝的方式。

備忘

這個系列不是一個大而全的package api 指南,只包括作者認為最常見的使用方式。抗議無效。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.