#go
#Вперед
Вопрос:
Ниже у меня есть пример одной структуры, которая встраивает другую. Я пытаюсь выяснить, как передать более конкретный указатель структуры для сохранения в менее конкретной. Вы можете думать об этом как о коллекции. Перенос в интерфейс, похоже, не работает, поскольку это привело бы к созданию копии, что недопустимо для структур с блокировками. Идеи?
package stackoverflow
import "sync"
type CoolerThingWithLock struct {
fancyStuff string
ThingWithLock
}
func NewCoolerThingWithLock() *CoolerThingWithLock {
coolerThingWithLock := amp;CoolerThingWithLock{}
coolerThingWithLock.InitThingWithLock()
return coolerThingWithLock
}
type ThingWithLock struct {
value int
lock sync.Mutex
children []*ThingWithLock
}
func (thingWithLock *ThingWithLock) InitThingWithLock() {
thingWithLock.children = make([]*ThingWithLock, 0)
}
func NewThingWithLock() *ThingWithLock {
newThingWithLock := amp;ThingWithLock{}
newThingWithLock.InitThingWithLock()
return newThingWithLock
}
func (thingWithLock *ThingWithLock) AddChild(newChild *ThingWithLock) {
thingWithLock.children = append(thingWithLock.children, newChild)
}
func (thingWithLock *ThingWithLock) SetValue(newValue int) {
thingWithLock.lock.Lock()
defer thingWithLock.lock.Unlock()
thingWithLock.value = newValue
for _, child := range thingWithLock.children {
child.SetValue(newValue)
}
}
func main() {
thingOne := NewThingWithLock()
thingTwo := NewCoolerThingWithLock()
thingOne.AddChild(thingTwo)
thingOne.SetValue(42)
}
Ошибка: не удается использовать thingTwo (тип * CoolerThingWithLock) в качестве типа
*ThingWithLock в аргументе thingOne.addChild
Ответ №1:
Невозможно сохранить тип упаковки в []*ThignWithLock
, поскольку go не имеет понятия о структурном подтипе.
Ваше утверждение о том, что интерфейс приведет к копированию, неверно, и вы можете получить желаемый эффект, выполнив:
type InterfaceOfThingThatParticipatesInAHierarchy interface {
AddChild(InterfaceOfThingThatParticipatesInAHierarchy)
SetValue(int)
}
type ThingWithLock struct {
...
children []InterfaceOfThingThatParticipatesInAHierarchy
}
func (thingWithLock *ThingWithLock) AddChild(newChild InterfaceOfThingThatParticipatesInAHierarchy) { ... }
До тех пор, пока интерфейс реализован на *ThingWithLock
и не ThingWithLock
, не будет копирования самой структуры получателя, в стек будет скопирован только указатель на структуру.
Комментарии:
1. Потрясающе, это именно то, что я искал. Спасибо за помощь! 🙂