当您通过值或指针访问另一个结构时有什么区别? 什么时候应该使用它们?
type foo_ struct {
st uint8
nd uint8
}
type bar struct {
rd uint8
foo foo_
}
type barP struct {
rd uint8
foo *foo_
}
答案 0 :(得分:5)
如果您声明或分配type bar
变量,则为rd uint8
和foo foo_
保留并初始化为零内存。 type foo_
变量中始终存在type bar
的一个变量。
var b bar // declare b
如果您声明或分配type barP
变量,则为rd uint8
和foo *foo_
保留并初始化为零内存。零值指针是nil
指针。没有分配type foo_
的变量;你必须分开做。变量foo == nil
指向零(type foo_
)或type barP
的一个变量。变量type barP
可能指向与type foo_
的其他变量相同的type barP
变量,共享type foo_
变量的相同副本。所有指向它的变量都会看到对共享副本的更改。
var bp barP // declare bp
bp.foo = new(foo_) // allocate bp.foo
使用哪一项取决于type bar
与type barP
的属性。哪种类型更能反映出您试图解决的问题?
例如,请考虑此发票问题。我们总是有账单地址;我们总是要求我们的钱。但是,我们经常发送到帐单邮寄地址,但并非总是如此。如果送货地址为nil
,请使用帐单邮寄地址。否则,请使用单独的送货地址。我们有两个仓库,我们总是从一个或另一个出货。我们可以共享两个仓库位置。由于我们在订单从仓库发货之前不发送发票,因此仓库位置永远不会是nil
。
type address struct {
street string
city string
}
type warehouse struct {
address string
}
type invoice struct {
name string
billing address
shipping *address
warehouse *warehouse
}
答案 1 :(得分:2)
答案很大程度上与语言无关 - C语言中的等价物具有相同的问题。
当你有一个嵌入值(如在bar
中)时,你的结构就足以容纳完整的子结构和另一部分。
当你有一个指向某个值的指针时(如barP
所示),那么barP
类型的多个结构可能共享相同的foo
。当barP
中的任何一个修改了它所指向的foo
的一部分时,它会影响指向同一位置的所有其他barP
结构。此外,正如评论所建议的那样,您必须管理两个单独的对象 - barP
和foo
,而不是普通bar
类型的对象。
在某些语言中,你不得不担心悬挂指针和未初始化的值等; Go是垃圾收集的,通常比其他语言更安全。
因此,当您希望多个barP
个对象共享同一个foo
对象时,请使用指针;否则,使用显式成员对象,而不是指向对象的指针。