在golang中嵌入了锁的通用结构的集合

时间:2016-10-23 21:15:27

标签: go

下面我有一个嵌入另一个结构的例子。我试图弄清楚如何传递更具体的结构指针,以存储在一个不太具体的结构。你可以把它想象成一个集合。在接口中包装似乎不起作用,因为这样做会产生一个副本,这对于带有锁的结构是无效的。想法?

package stackoverflow

import "sync"

type CoolerThingWithLock struct {
    fancyStuff string
    ThingWithLock
}

func NewCoolerThingWithLock() *CoolerThingWithLock {
    coolerThingWithLock := &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 := &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)作为类型   *在thingOne.AddChild的参数中使用ThingWithLock

1 个答案:

答案 0 :(得分:2)

[]*ThignWithLock中存储包装类型是不可能的,因为go没有结构子类型的概念。

您断言接口将导致复制is incorrect,您可以通过执行以下操作获得所需的效果:

type InterfaceOfThingThatParticipatesInAHierarchy interface {
    AddChild(InterfaceOfThingThatParticipatesInAHierarchy)
    SetValue(int)
}

type ThingWithLock struct {
    ...
    children []InterfaceOfThingThatParticipatesInAHierarchy
}

func (thingWithLock *ThingWithLock) AddChild(newChild InterfaceOfThingThatParticipatesInAHierarchy) { ... }

只要接口是在*ThingWithLock而不是ThingWithLock上实现的,就不会复制接收器结构本身,只会将指向结构的指针复制到堆栈上。 / p>