基本序列化
本指南介绍 Fory Go 的核心序列化 API。
创建 Fory 实例
在序列化前先创建 Fory 实例并注册类型:
import "github.com/apache/fory/go/fory"
f := fory.New()
// Register struct with a type ID
f.RegisterStruct(User{}, 1)
f.RegisterStruct(Order{}, 2)
// Or register with a name (more flexible, less prone to ID conflicts, but higher serialization cost)
f.RegisterNamedStruct(User{}, "example.User")
// Register enum types
f.RegisterEnum(Color(0), 3)
重要:应在多次序列化调用间复用同一个 Fory 实例。创建新实例会分配内部缓冲区、类型缓存和解析器,开销较高。默认实例不是线程安全的;并发场景请使用线程安全封装(见 线程安全)。
更多内容请参考 类型注册。
核心 API
Serialize 与 Deserialize
最主要的序列化接口:
// Serialize any value
data, err := f.Serialize(value)
if err != nil {
// Handle error
}
// Deserialize into target
var result MyType
err = f.Deserialize(data, &result)
if err != nil {
// Handle error
}
Marshal 与 Unmarshal
Serialize 和 Deserialize 的别名(对 Go 开发者更熟悉):
data, err := f.Marshal(value)
err = f.Unmarshal(data, &result)
序列化基础类型
// Integers
data, _ := f.Serialize(int64(42))
var i int64
f.Deserialize(data, &i) // i = 42
// Floats
data, _ = f.Serialize(float64(3.14))
var fl float64
f.Deserialize(data, &fl) // fl = 3.14
// Strings
data, _ = f.Serialize("hello")
var s string
f.Deserialize(data, &s) // s = "hello"
// Booleans
data, _ = f.Serialize(true)
var b bool
f.Deserialize(data, &b) // b = true
序列化集合类型
Slice
// String slice
strs := []string{"a", "b", "c"}
data, _ := f.Serialize(strs)
var result []string
f.Deserialize(data, &result)
// result = ["a", "b", "c"]
// Integer slice
nums := []int64{1, 2, 3}
data, _ = f.Serialize(nums)
var intResult []int64
f.Deserialize(data, &intResult)
// intResult = [1, 2, 3]
Map
// String to string map
m := map[string]string{"key": "value"}
data, _ := f.Serialize(m)
var result map[string]string
f.Deserialize(data, &result)
// result = {"key": "value"}
// String to int map
m2 := map[string]int64{"count": 42}
data, _ = f.Serialize(m2)
var result2 map[string]int64
f.Deserialize(data, &result2)
// result2 = {"count": 42}
序列化结构体
基础结构体序列化
只有导出字段(首字母大写)会被序列化:
type User struct {
ID int64 // Serialized
Name string // Serialized
password string // NOT serialized (unexported)
}
f.RegisterStruct(User{}, 1)
user := &User{ID: 1, Name: "Alice", password: "secret"}
data, _ := f.Serialize(user)
var result User
f.Deserialize(data, &result)
// result.ID = 1, result.Name = "Alice", result.password = ""
嵌套结构体
type Address struct {
City string
Country string
}
type Person struct {
Name string
Address Address
}
f.RegisterStruct(Address{}, 1)
f.RegisterStruct(Person{}, 2)
person := &Person{
Name: "Alice",
Address: Address{City: "NYC", Country: "USA"},
}
data, _ := f.Serialize(person)
var result Person
f.Deserialize(data, &result)
// result.Address.City = "NYC"
指针字段
type Node struct {
Value int32
Child *Node
}
// Use WithTrackRef for pointer fields
f := fory.New(fory.WithTrackRef(true))
f.RegisterStruct(Node{}, 1)
root := &Node{
Value: 1,
Child: &Node{Value: 2, Child: nil},
}
data, _ := f.Serialize(root)
var result Node
f.Deserialize(data, &result)
// result.Child.Value = 2
流式 API
当你希望自行管理缓冲区时可使用流式接口。
SerializeTo
序列化到现有缓冲区:
buf := fory.NewByteBuffer(nil)
// Serialize multiple values to same buffer
f.SerializeTo(buf, value1)
f.SerializeTo(buf, value2)
// Get all serialized data
data := buf.GetByteSlice(0, buf.WriterIndex())
DeserializeFrom
从现有缓冲区反序列化:
buf := fory.NewByteBuffer(data)
var result1, result2 MyType
f.DeserializeFrom(buf, &result1)
f.DeserializeFrom(buf, &result2)