Если вы объявляете или выделяете переменную 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
}