isayme / blog

https://blog.isayme.org
MIT License
10 stars 2 forks source link

使用 monkey 替换 Golang 标准库方法 #20

Open isayme opened 5 years ago

isayme commented 5 years ago

Golang 标准库的json.Marshal & json.Unmarshal 方法性能并不高. 因而产生了第三方包解决此问题. 如: ffjson, json-iterator, easyjson.

但开发者在又序列化需求时一般都会使用 encoding/jsonjson.* 系方法. 第三方包需要新增依赖, 在性能不是瓶颈时自然更倾向于使用官方原生包. 毕竟官方包也会持续对性能做改进.

但如果真有需要替换掉json.Marshal 时又如何做呢? 解决方法是 Monkey patching in Go:

package main

import (
    "encoding/json"
    "fmt"

    "github.com/bouk/monkey"
    jjson "github.com/json-iterator/go"
)

type User struct {
    Name   string   `json:"name"`
    Emails []string `json:"emails"`
}

func main() {
    monkey.Patch(json.Marshal, func(v interface{}) ([]byte, error) {
        fmt.Println("use jsoniter")
        return jjson.Marshal(v)
    })

    u := User{}

    if b, err := json.Marshal(u); err != nil {
        fmt.Println("Marshal failed: ", err)
    } else {
        fmt.Println(err, string(b))
    }
}

虽然使用的还是 json.Marshal, 实际调用的已经是 Patch 后的方法. 此代码输出:

use jsoniter
<nil> {"name":"","emails":null}

参考资料