H5W3
当前位置:H5W3 > go > 正文

【go】Golang是否可以通过反射来实现这种操作?

【go】Golang是否可以通过反射来实现这种操作?

如图所示代码中的resolveMessage函数用于该模块定义的一个struct来拆分收到的数据包,也就是该函数的参数data。比如说收到一个data为“101|testname”,那么就自动将其转成结构体PassportMsg{101,testname}。

这个拆包函数在多个模块都会用到,但是每个模块的结构体并不一样,甚至还有的结构体又嵌套了别的结构体

请问能否通过反射来自动根据结构体的定义,将字符串转换成指定结构体?

可以但不推荐,有些场景还可能做不到
比如

type A struct {
Code int
Msg string
}
type B struct {
Code int
Name string
}

那么应该反序列化哪一个呢?
推荐json
如果非要用A|B这种,那就根据CmdId来决定哪一个结构
反射, 而且用到这里代码耦合

  • 字符串data和目标结构体怎么对应呢?这点我不知道其中的业务逻辑,即字符串101|testname是怎么对应上某个结构体的呢?即使像你说的用反射,那反射拿到结构体metadata后又怎么和这个字符串对应呢?假设这个字符串中包含了某个属性名,那按照属性名可以和反射得到的结构体属性对应上,这算是一种对应逻辑。所以说,这不是技术上能不能实现的问题,是个业务问题。
  • 既然不同的结构体所对应的解析函数会有所不同,那应该给每个结构体定义一个解析函数。

    type ResolveFunc func(data string) *PassportMsg
    func resolveMessage(data string, f ResolveFunc) *PassportMsg{
    // 其他代码逻辑
    return f(data)
    }

反射其实是可以来做这种解码的,无非就是遍历整个结构体的元信息,然后依次从字符串里面提取并转换下类型就行了。

但是,题主这种用”|”分割编码方式有相当大的缺陷 — 有没有考虑过这个问题:

假如有下面这样一个结构体:

type A struct {
Code int
Msg string
Sender string
}

而有个消息是 "101|这段shell代码 cat hello.txt | wc -l 怎么没法工作呀?|Jim",你怎么解码?

Msg本来是"这段shell代码 cat hello.txt | wc -l 怎么没法工作呀?", 但是小心别解码成了"这段shell代码 cat hello.txt ".

使用定界符的编码方式都会遇到这种问题。

当然题主的场景中是否会遇到这种问题尚未可知,提醒下。

解决方法自然是有的,可以参考JSON和BSON。

回答

本文地址:H5W3 » 【go】Golang是否可以通过反射来实现这种操作?

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址