标准库的常用反序列化接口,如UnmarshalText(text []byte) error
其实也是支持的哟,使用方式同UnmarshalValue
,只是参数不同。
接口定义
可以看到,自定义的类型可以通过定义UnmarshalValue
方法来实现自定义的类型转换。这里的输入参数为interface{}
类型,开发者可以在实际使用场景中通过 类型断言 或者其他方式进行类型转换。
需要特别注意,由于UnmarshalValue
类型转换会修改当前对象的属性值,因此需要保证该接口实现的接受者(Receiver
)是指针类型。
func (c *Receiver) UnmarshalValue(interface{}) error
错误的接口实现定义示例(使用了值传递):
使用示例
数据表结构:
CREATE TABLE `user` (
id bigint unsigned NOT NULL AUTO_INCREMENT,
passport varchar(45),
password char(32) NOT NULL,
nickname varchar(45) NOT NULL,
create_time timestamp NOT NULL,
PRIMARY KEY (id)
) ;
示例代码:
[
{
"Id": 1,
"Passport": "user_1",
"Password": "",
"Nickname": "name_1",
"CreateTime": "2018-10-24 10:00:00"
{
"Id": 2,
"Passport": "user_2",
"Password": "",
"Nickname": "name_2",
"CreateTime": "2018-10-24 10:00:00"
},
{
"Passport": "user_3",
"Password": "",
"Nickname": "name_3",
"CreateTime": "2018-10-24 10:00:00"
},
{
"Id": 4,
"Passport": "user_4",
"Password": "",
"Nickname": "name_4",
"CreateTime": "2018-10-24 10:00:00"
},
{
"Id": 5,
"Passport": "user_5",
"Password": "",
"Nickname": "name_5",
"CreateTime": "2018-10-24 10:00:00"
},
{
"Id": 6,
"Passport": "user_6",
"Password": "",
"Nickname": "name_6",
},
{
"Id": 7,
"Password": "",
"Nickname": "name_7",
"CreateTime": "2018-10-24 10:00:00"
},
{
"Id": 8,
"Passport": "user_8",
"Password": "",
"Nickname": "name_8",
"CreateTime": "2018-10-24 10:00:00"
},
{
"Id": 9,
"Passport": "user_9",
"Password": "",
"Nickname": "name_9",
"CreateTime": "2018-10-24 10:00:00"
},
{
"Id": 10,
"Passport": "user_10",
"Password": "",
"Nickname": "name_10",
"CreateTime": "2018-10-24 10:00:00"
}
]
可以看到自定义的UnmarshalValue
类型转换方法中没有使用到反射特性,因此转换的性能会得到极大的提升。小伙伴们可以尝试着增加写入的数据量(例如100W
),同时对比一下去掉UnmarshalValue
后的类型转换所开销的时间。
2、自定义二进制TCP数据解包
一个TCP通信的数据包解包示例。
执行后,终端输出:
&{9 2286445522 [49 50 51]}