为何AWS ION自定义UnmarshalIon方法未被调用?
问题分析与解决方案
你的代码有两个核心问题导致UnmarshalIon方法未被调用:
ION Reader 未定位到有效数据
ion.NewReader创建的Reader初始处于流起始(StreamStart)状态,此时没有可解析的数据单元。ion.UnmarshalFrom在这种状态下无法触发自定义反序列化逻辑,因为它找不到需要处理的目标值。自定义方法未处理Reader状态(隐性问题)
即使Reader位置正确,你的UnmarshalIon方法没有推进Reader的读取位置,会导致后续操作异常;但更关键的是,未定位到有效数据时,方法本身就不会被触发。
修改后的完整代码
package main import ( "bytes" "fmt" "github.com/amzn/ion-go/ion" ) func main() { UnmarshalCustomMarshaler() } type unmarshalMe struct { Name string custom bool } func (u *unmarshalMe) UnmarshalIon(r ion.Reader) error { fmt.Println("UnmarshalIon called") // 推进Reader到第一个有效数据单元 t, err := r.Next() if err != nil { return err } // 处理结构体类型数据 if t == ion.StructType { for field, err := r.Field(); err == nil; field, err = r.Field() { if field == "Name" { name, err := r.StringValue() if err != nil { return err } u.Name = name } // 跳过当前字段,推进Reader位置 if err := r.Skip(); err != nil { return err } } } u.custom = true return nil } func UnmarshalCustomMarshaler() { ionBinary, err := ion.MarshalBinary(unmarshalMe{ Name: "John Doe", }) if err != nil { fmt.Println("Error marshalling ion binary: ", err) panic(err) } dec := ion.NewReader(bytes.NewReader(ionBinary)) // 提前将Reader定位到第一个有效数据 if _, err := dec.Next(); err != nil { fmt.Println("Error advancing reader: ", err) panic(err) } var decodedResult unmarshalMe err = ion.UnmarshalFrom(dec, &decodedResult) if err != nil { fmt.Println("Error unmarshalling: ", err) panic(err) } fmt.Println("Decoded result: ", decodedResult) }
关键修改说明
- 提前定位Reader:在调用
ion.UnmarshalFrom前,通过dec.Next()将Reader推进到第一个有效数据单元,确保自定义反序列化方法能被触发。 - 完善Reader处理逻辑:在
UnmarshalIon方法中,添加了数据类型判断、字段遍历和Reader位置推进的逻辑,既保证了字段值的正确读取,也避免了后续操作的异常。 - 调整输出方式:将
fmt.Print改为fmt.Println,避免输出缓冲导致的内容不显示问题。
内容的提问来源于stack exchange,提问作者Vingtoft
相关产品推荐
相关产品推荐

