Golang中使用结构体实现泛型

Golang中使用结构体实现泛型 以下是我在我的数据库工具 Bobb 中使用 Go 泛型的示例。问题案例是以泛型方式将数据库记录结构体类型转换为字节切片 []byte,然后再转换回原始结构体类型。处理单个记录很简单,但记录切片和映射则是更复杂的问题。我可能忽略了一些看似简单但一直没找到的解决方案。

讨论链接

1 回复

更多关于Golang中使用结构体实现泛型的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,结构体本身不支持泛型,但可以通过泛型函数或方法实现类似功能。根据你的需求,处理数据库记录结构体类型与字节切片之间的转换,特别是针对切片和映射,可以使用泛型函数结合encoding/jsongob等序列化方式实现。以下是一个使用json.Marshaljson.Unmarshal的泛型实现示例,适用于单个记录、切片和映射。

package main

import (
    "encoding/json"
    "fmt"
)

// 泛型函数:将任意类型转换为字节切片
func ToBytes[T any](data T) ([]byte, error) {
    return json.Marshal(data)
}

// 泛型函数:将字节切片转换回原始类型
func FromBytes[T any](b []byte) (T, error) {
    var data T
    err := json.Unmarshal(b, &data)
    return data, err
}

// 示例结构体
type Record struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
}

func main() {
    // 单个记录转换
    record := Record{ID: 1, Name: "Test"}
    bytes, err := ToBytes(record)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("Bytes:", bytes)

    var decodedRecord Record
    decodedRecord, err = FromBytes[Record](bytes)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("Decoded Record:", decodedRecord)

    // 切片转换
    records := []Record{{ID: 1, Name: "A"}, {ID: 2, Name: "B"}}
    sliceBytes, err := ToBytes(records)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    var decodedSlice []Record
    decodedSlice, err = FromBytes[[]Record](sliceBytes)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("Decoded Slice:", decodedSlice)

    // 映射转换
    recordMap := map[int]Record{1: {ID: 1, Name: "MapTest"}}
    mapBytes, err := ToBytes(recordMap)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    var decodedMap map[int]Record
    decodedMap, err = FromBytes[map[int]Record](mapBytes)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("Decoded Map:", decodedMap)
}

这个示例中,ToBytesFromBytes 是泛型函数,可以处理任意类型 T,包括结构体、切片和映射。通过 json.Marshaljson.Unmarshal 实现序列化和反序列化。注意,这种方法依赖于JSON标签,如果结构体字段未导出或缺少标签,可能会导致错误。对于更复杂的场景,可以考虑使用 gob 或其他二进制序列化库,但原理类似。

回到顶部