Unserialize 函数

    1. func Unserialize(b []byte, p interface{}, simple bool)

    将字节切片数据 b 反序列化到 p 所指向的变量中,p 是一个指向反序列化变量的指针。simple 参数的含义与 Reader 结构体的序列化的 参数相同。

    Marshal 函数

    1. func Marshal(v interface{}) []byte

    相当于 Serialize(v, true)

    1. func Unmarshal(b []byte, p interface{})

    相当于 Unserialize(b, p, true)

    RegisterSliceEncoder 函数

    1. func RegisterSliceEncoder(s interface{}, encoder func(*Writer, interface{}))

    该函数用于注册一个 slice 编码器实现对 slice 的快速的 hprose 序列化。hprose 对如下 slice 类型已经提供了内置的快速编码器:

    • []bool
    • []int
    • []int8
    • []int16
    • []int32
    • []int64
    • []uint
    • []uint8
    • []uint16
    • []uint32
    • []uint64
    • []uintptr
    • []float32
    • []float64
    • []complex64
    • []complex128
    • []string
    • [][]byte

    对于没有提供快速编码器的类型,hprose 采用反射的方式进行序列化。如果用户想要加快某个复杂的 slice 类型的序列化,可以使用该函数来注册自定义编码器,下面来看一个例子:

    该程序运行结果为:

    1. 844
    2. 664

    我们看到,实现快速编码器之后,效率提高了大约 20% 左右。当然实现快速编码器需要了解 hprose 的编码规范。如果上面的编码器只是实现为:

    1. func mySliceEncoder(w *io.Writer, v interface{}) {
    2. slice := v.([]map[string]interface{})
    3. for i := range slice {
    4. w.Serialize(slice[i])
    5. }
    6. }

    RegisterSliceEncoder 函数的第一个参数是编码器所要序列化的数据类型的一个实例。它必须是一个 slice 类型的实例,并且跟后面注册的编码器中所序列化的类型相一致。

    RegisterMapEncoder 函数

    1. func RegisterMapEncoder(m interface{}, encoder func(*Writer, interface{}))

    该函数用于注册一个 map 编码器实现对 map 的快速的 hprose 序列化。hprose 对如下 map 类型已经提供了内置的快速编码器:

    • map[string]string
    • map[string]interface{}
    • map[string]int
    • map[int]int
    • map[int]string
    • map[int]interface{}
    • map[interface{}]interface{}
    • map[interface{}]int
    • map[interface{}]string
      用户不需要为上述 map 类型注册自定义编码器。

    对于没有提供快速编码器的类型,hprose 采用反射的方式进行序列化。如果用户想要加快某个其它 map 类型的序列化,可以使用该函数来注册自定义编码器,下面来看一个例子:

    1. package main
    2.  
    3. import (
    4. "fmt"
    5. "math"
    6. "time"
    7.  
    8. "github.com/hprose/hprose-golang/io"
    9. )
    10.  
    11. func stringFloat64MapEncoder(w *io.Writer, v interface{}) {
    12. m := v.(map[string]float64)
    13. for key, val := range m {
    14. w.WriteString(key)
    15. }
    16. }
    17.  
    18. func test(m map[string]float64) {
    19. start := time.Now()
    20. for i := 0; i < 500000; i++ {
    21. io.Marshal(m)
    22. }
    23. stop := time.Now()
    24. fmt.Println((stop.UnixNano() - start.UnixNano()) / 1000000)
    25. }
    26.  
    27. func main() {
    28. m := make(map[string]float64)
    29. m["e"] = math.E
    30. m["pi"] = math.Pi
    31. m["ln2"] = math.Ln2
    32. test(m)
    33. io.RegisterMapEncoder((map[string]float64)(nil), stringFloat64MapEncoder)
    34. test(m)
    35. }

    该程序运行结果为:

    我们看到,实现快速编码器之后,效率提高了大约 35% 左右。

    RegisterMapEncoder 函数的第一个参数是编码器所要序列化的数据类型的一个实例。它必须是一个 map 类型的实例,并且跟后面注册的编码器中所序列化的类型相一致。

    1. func Register(proto interface{}, alias string, tag ...string)

    该函数用于注册一个可序列化和反序列化的自定义结构体。

    第二个参数 alias 为注册的结构体的别名,该名称可以跟结构体类型名称相同,也可以不同。它用于在不同语言的不同定义之间进行类型映射。

    第三个参数 是可选的(可以是 0 个或 1 个,但不支持多个),它用于指定序列化字段别名的 tag 标签名。

    假设有如下结构体定义:

    1. type User struct {
    2. Name string `json:"name"`
    3. Age int `json:"age"`
    4. Password string `json:"-"`
    5. }

    那么可以这样注册:

    1. func init() {
    2. io.Register((*User)(nil), "User", "json")
    3. }

    注册之后的 User 类型的对象,在序列化时,字段名按照 json 标签对应的名称进行序列化,如果 json 标签对应的名称为 "-",那么该字段将不会被序列化。另外,私有字段也不会被序列化。当没有指定标签时,字段名会自动按照小写首字母的名称进行序列化。

    GetStructType 函数

    1. func GetStructType(alias string) (structType reflect.Type)

    获取用 Register 函数注册的类型。

    GetAlias 函数

    获取用 Register 函数注册的类型对应的别名。

    1. func GetTag(structType reflect.Type) string