标准库的常用反序列化接口,如UnmarshalText(text []byte) error其实也是支持的哟,使用方式同UnmarshalValue,只是参数不同。

接口定义

可以看到,自定义的类型可以通过定义UnmarshalValue方法来实现自定义的类型转换。这里的输入参数为interface{}类型,开发者可以在实际使用场景中通过 类型断言 或者其他方式进行类型转换。

需要特别注意,由于UnmarshalValue类型转换会修改当前对象的属性值,因此需要保证该接口实现的接受者(Receiver)是指针类型。

  1. func (c *Receiver) UnmarshalValue(interface{}) error

错误的接口实现定义示例(使用了值传递):

使用示例

数据表结构:

  1. CREATE TABLE `user` (
  2. id bigint unsigned NOT NULL AUTO_INCREMENT,
  3. passport varchar(45),
  4. password char(32) NOT NULL,
  5. nickname varchar(45) NOT NULL,
  6. create_time timestamp NOT NULL,
  7. PRIMARY KEY (id)
  8. ) ;

示例代码:

  1. [
  2. {
  3. "Id": 1,
  4. "Passport": "user_1",
  5. "Password": "",
  6. "Nickname": "name_1",
  7. "CreateTime": "2018-10-24 10:00:00"
  8. {
  9. "Id": 2,
  10. "Passport": "user_2",
  11. "Password": "",
  12. "Nickname": "name_2",
  13. "CreateTime": "2018-10-24 10:00:00"
  14. },
  15. {
  16. "Passport": "user_3",
  17. "Password": "",
  18. "Nickname": "name_3",
  19. "CreateTime": "2018-10-24 10:00:00"
  20. },
  21. {
  22. "Id": 4,
  23. "Passport": "user_4",
  24. "Password": "",
  25. "Nickname": "name_4",
  26. "CreateTime": "2018-10-24 10:00:00"
  27. },
  28. {
  29. "Id": 5,
  30. "Passport": "user_5",
  31. "Password": "",
  32. "Nickname": "name_5",
  33. "CreateTime": "2018-10-24 10:00:00"
  34. },
  35. {
  36. "Id": 6,
  37. "Passport": "user_6",
  38. "Password": "",
  39. "Nickname": "name_6",
  40. },
  41. {
  42. "Id": 7,
  43. "Password": "",
  44. "Nickname": "name_7",
  45. "CreateTime": "2018-10-24 10:00:00"
  46. },
  47. {
  48. "Id": 8,
  49. "Passport": "user_8",
  50. "Password": "",
  51. "Nickname": "name_8",
  52. "CreateTime": "2018-10-24 10:00:00"
  53. },
  54. {
  55. "Id": 9,
  56. "Passport": "user_9",
  57. "Password": "",
  58. "Nickname": "name_9",
  59. "CreateTime": "2018-10-24 10:00:00"
  60. },
  61. {
  62. "Id": 10,
  63. "Passport": "user_10",
  64. "Password": "",
  65. "Nickname": "name_10",
  66. "CreateTime": "2018-10-24 10:00:00"
  67. }
  68. ]

可以看到自定义的UnmarshalValue类型转换方法中没有使用到反射特性,因此转换的性能会得到极大的提升。小伙伴们可以尝试着增加写入的数据量(例如100W),同时对比一下去掉UnmarshalValue后的类型转换所开销的时间。

2、自定义二进制TCP数据解包

一个TCP通信的数据包解包示例。

执行后,终端输出:

  1. &{9 2286445522 [49 50 51]}