apache/dubbo-go-hessian2

Java's Extends and Go's Embed: Java 继承与 Go 嵌入字段

micln opened this issue · 0 comments

micln commented

本文描述 dubbo-go-hessian2 如何处理 Java 中的继承。

为便于描述,下文会用一些特定的名词:

  • hessian 表示 Java 版本的 hessian 库
  • go-hessian2 用来指当前库。

Java 继承

Hessian 在序列化继承时,会将父类的属性展开到子类里(效果等同于把这些字段定义在子类里)。也就是说,在 hessian 的编码里,我们无法区分出这个字段是来自当前的类还是父类。所以我们做的工作就是把这些字段一一映射到 Go 的 struct 里。

Go 嵌入字段(匿名字段)

在 Go 里是没有继承这一概念的,但一般的,我们用匿名字段的方式来达到类似继承的字段复用效果。这是我们必须面临的问题,因此我们特别的支持了如下这种情况

Java Go
image image

由于上面提到的原因,我们其实无法识别这个 name 字段是父类的还是子类的,所以对于这个 Java 类,下面这段 Go 定义也是可以识别的。

type Dog struct {
	Name string
}

一般情况下,这些足够使用了。因此对于一些复杂的情况,我们并未完全处理。

暂不支持的情况

Go 里多个匿名字段拥有同样的字段名

type A struct { Name string }
type B struct { Name string }
type C struct {
	A
	B
}

这个结构体 C 有两个叫 Name 的字段,在 Go 官方的 json 库里会把两个都忽略掉。但 go-hessian2 并没有做类似的工作。因为无论怎么处理,都会让人难以理解,开发者应该避免使用这样的用法。如果因为一些失误确实定义了重复的字段,可以使用 hessian:"-" 来忽略其中一个( json 库也支持这样处理)

指针类型的匿名字段

type Dog struct {
	*Animal
}

尽管 Go 里可以这样定义结构体。但是Java 里的父类是不可能为空的,hessian 协议当然也不支持。所以 go-hessian2 也不支持这样的继承。