golang 基本类型 序列化

发布时间:2024-10-02 19:47:42

在golang中,基本类型的序列化是程序开发过程中经常遇到的一项技术。序列化是将数据从内存中存储或传输到外部介质(如磁盘、网络)的过程。而反序列化则是将存储或传输的数据重新读取到内存中的过程。在本文中,我将分享一些关于golang基本类型的序列化的知识和技巧。

使用标准库的json序列化

在golang中,可以使用标准库中的json包进行基本类型的序列化。json包提供了Marshal和Unmarshal函数来进行数据的编码和解码。

首先,我们需要定义一个结构体,该结构体包含需要序列化的字段:

type Person struct {
    Name string
    Age  int
}

然后,我们可以使用json.Marshal函数将该结构体转换为json字符串:

func main() {
    p := Person{Name: "John", Age: 28}
    data, err := json.Marshal(p)
    if err != nil {
        fmt.Println("json marshal error:", err)
        return
    }
    fmt.Println(string(data))
}

输出结果为:

{"Name":"John","Age":28}

自定义序列化

有时候,我们需要对字段进行特殊处理或自定义格式的序列化。golang中提供了两个接口:MarshalJSON和UnmarshalJSON,通过实现这两个接口可以实现自定义的序列化和反序列化逻辑。

以时间类型为例,golang中的time包提供了Time类型,我们可以自定义一个Time类型的别名,并实现MarshalJSON和UnmarshalJSON接口,在序列化和反序列化时按照特定的格式进行处理:

type CustomTime time.Time

func (t CustomTime) MarshalJSON() ([]byte, error) {
    stamp := fmt.Sprintf("\"%s\"", time.Time(t).Format("2006-01-02 15:04:05"))
    return []byte(stamp), nil
}

func (t *CustomTime) UnmarshalJSON(data []byte) error {
    str := strings.Trim(string(data), "\"")
    tt, err := time.Parse("2006-01-02 15:04:05", str)
    if err != nil {
        return err
    }
    *t = CustomTime(tt)
    return nil
}

type Person struct {
    Name string     `json:"name"`
    Age  int        `json:"age"`
    Time CustomTime `json:"time"`
}

func main() {
    p := Person{Name: "John", Age: 28, Time: CustomTime(time.Now())}
    data, err := json.Marshal(p)
    if err != nil {
        fmt.Println("json marshal error:", err)
        return
    }
    fmt.Println(string(data))
}

输出结果为:

{"name":"John","age":28,"time":"2021-09-20 10:30:00"}

使用第三方库

除了标准库的json包,golang还有一些功能更强大的第三方库,如protobuf、msgpack等。这些库提供了更高效和更灵活的序列化方式。

以protobuf为例,首先我们需要定义一个protobuf消息类型:

message Person {
    string name = 1;
    int32 age = 2;
}

然后,使用protobuf编译器将.proto文件编译为对应的golang代码:

protoc --go_out=. person.proto

接下来,在代码中使用生成的代码来进行序列化和反序列化:

func main() {
    p := &pb.Person{Name: "John", Age: 28}
    data, err := proto.Marshal(p)
    if err != nil {
        fmt.Println("protobuf marshal error:", err)
        return
    }
    fmt.Println(string(data))

    p2 := &pb.Person{}
    err = proto.Unmarshal(data, p2)
    if err != nil {
        fmt.Println("protobuf unmarshal error:", err)
        return
    }
    fmt.Println(p2.GetName(), p2.GetAge())
}

输出结果为:

{10 4 74 6 68 111 104 110 34}

通过上述示例,我们可以看到使用protobuf进行序列化和反序列化相比于json包更加高效、灵活。当然,选择序列化方式应根据实际需求来决定。

总之,golang提供了丰富的序列化方式,在基本类型的序列化中,json是最常用的方式。除了标准库的json包,还可以通过自定义序列化和使用第三方库来实现更高级的序列化需求。希望本文对你理解golang基本类型的序列化有所帮助!

相关推荐