设计思路
- 遍历结构体字段:使用Go的反射机制获取结构体的类型和值。通过
reflect.TypeOf
和reflect.ValueOf
函数来操作。
- 处理不同类型字段:
- 基本类型:直接获取其值并转换为字符串。
- 切片:递归处理切片中的每个元素。
- 嵌套结构体:同样递归进行序列化。
- 构建序列化字符串:按照类似JSON的格式,使用
strings.Builder
来高效构建字符串。
关键实现代码
package main
import (
"fmt"
"reflect"
"strings"
)
func serialize(obj interface{}) string {
var sb strings.Builder
sb.WriteByte('{')
value := reflect.ValueOf(obj)
typ := reflect.TypeOf(obj)
for i := 0; i < value.NumField(); i++ {
fieldValue := value.Field(i)
fieldType := typ.Field(i)
sb.WriteString(fmt.Sprintf("\"%s\":", fieldType.Name))
serializeField(fieldValue, &sb)
if i < value.NumField()-1 {
sb.WriteByte(',')
}
}
sb.WriteByte('}')
return sb.String()
}
func serializeField(field reflect.Value, sb *strings.Builder) {
switch field.Kind() {
case reflect.Struct:
sb.WriteByte('{')
for j := 0; j < field.NumField(); j++ {
subFieldValue := field.Field(j)
subFieldType := field.Type().Field(j)
sb.WriteString(fmt.Sprintf("\"%s\":", subFieldType.Name))
serializeField(subFieldValue, sb)
if j < field.NumField()-1 {
sb.WriteByte(',')
}
}
sb.WriteByte('}')
case reflect.Slice:
sb.WriteByte('[')
for k := 0; k < field.Len(); k++ {
serializeField(field.Index(k), sb)
if k < field.Len()-1 {
sb.WriteByte(',')
}
}
sb.WriteByte(']')
default:
sb.WriteString(fmt.Sprintf("%v", field.Interface()))
}
}
测试代码
func main() {
type Inner struct {
Name string
}
type Outer struct {
ID int
Data Inner
Tags []string
}
outer := Outer{
ID: 1,
Data: Inner{
Name: "example",
},
Tags: []string{"tag1", "tag2"},
}
result := serialize(outer)
fmt.Println(result)
}