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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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)
}

Error: cannot use thingTwo (type *CoolerThingWithLock) as type
*ThingWithLock in argument to thingOne.AddChild

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

您关于接口将导致复制的断言是不正确的,并且可以通过执行以下操作获得所需的效果:

1
2
3
4
5
6
7
8
9
10
11
type InterfaceOfThingThatParticipatesInAHierarchy interface {
    AddChild(InterfaceOfThingThatParticipatesInAHierarchy)
    SetValue(int)
}

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

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

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

  • 太棒了,这正是我想要的。 谢谢您的帮助!:)