1、java中的类
在java中实现一个链表,链表中的节点类我们一般用下面的Node类这种构造方式
class Node {
int value;
Node next;
}
其中,value属性保存该节点的值,next属性保存该节点的下一个节点的指针
2、golang的结构体
在golang中,类比java中类的实现,我们一般很容易写出这样的结构体实现
type Node struct {
value int
next Node
}
其中value保存该节点的值,next属性保存该节点的下一个节点的地址。但是这段代码会在编译器中报告 invalid recursive type Node 这个错误。这是因为golang的编译器会认为Node这个结构体里面还引用了一个Node结构体,这样一直递归下去,编译器不知道给Node这个结构体分配多少空间。
所以golang中节点的结构体应该是
type Node struct {
value int
next *Node
}
其中next是一个Node的指针类型,由于指针的空间大小是确定的(在32位机器上占用4个字节,在64位机器上占用8个字节),这样编译器就知道给Node这个结构体分配多少空间了,不会产生递归的问题。
3、思考
1、为什么java中可以在类的属性中引用自己本身呢?
因为在java中我们这样定义一个类
class Node {
int value;
Node next;
}
但是在java的解释器中,代码会这样解释
class Node {
int value;
*Node next;
}
解释器会自动将其解释成指针类型,这样就不会产生golang中递归调用的问题
2、golang中结构体不能引用自身,能引用别的结构体吗?
type A struct {
}
type B struct {
a A
}
如图,在B结构体中引用A结构体,这样代码不会报错,因为A的结构体的大小编译器已知。但是如果改成
type A struct {
b B
}
type B struct {
a A
}
这样代码又会报 invalid recursive type Node 这个错误,因为编译器不知道A和B的确切大小。所以以后在代码中为了防止出现这种错误,在结构体中引用其他的结构体一般最好都设置为指针类型。
4、参考
https://www.jianshu.com/p/f3b88513dbd8
https://www.codenong.com/8261058/
https://stackoverflow.com/questions/59935466/invalid-recursive-type-and-illegal-cycle-in-declaration-of