如何确保由通道和映射组成的 Struct 通过引用传递?

How to ensure that a Struct that is made up of channels and map gets passed by reference?

提问人:AC007 提问时间:2/7/2022 最后编辑:AC007 更新时间:2/8/2022 访问量:352

问:

我有以下结构,其中包含用于存储数据的通道和映射。我希望能够将该结构传递到函数中,以便利用这些通道,以便在它们被触发/收到消息后,使用它们来更新与之关联的映射。

我知道默认情况下,地图在发送到各种函数时会通过引用传递。即使它们包含在自定义结构中,情况也会相同吗?如何确保我的整个结构通过引用传递给函数,以便更新存储并利用其通道?

type CustomStrct struct {
Storage      map[string]string
RetrieveChannel    chan string
InsertChannel      chan string
}

这是我创建的一个构造函数,用于初始化结构的新实例:

func InitializeNewStore() CustomStrct {
    newCustomStruct := CustomStrct {
        Storage:      make(map[string]string),
        RetrieveChannel:    make(chan Request),
        InsertChannel:    make(chan Request),
       }
 
return newCustomStruct 
}
字典 struct pass-by-reference go-map

评论

1赞 colm.anseo 2/7/2022
Go 没有值引用。要实现您想要的,请传递指向 strict 的指针。Go 地图本质上是一个指针。
0赞 AC007 2/7/2022
我只是在输入我的问题时想到了这一点。这是否意味着我应该将变量传递到我的构造函数中,并使用那些在变量中传递的变量创建我的 Struct 的新实例?
1赞 colm.anseo 2/7/2022
你的构造函数很好。频道和地图需要初始化,并在使用之前在那里进行,这是完美的地方。struct
1赞 Cerise Limón 2/7/2022
通道和映射值是单个内部指针。无论值如何传递(在结构字段或其他方式中),该内部指针都不会更改。InitializeNewStore 中的代码是一个很好的示例,说明如何在使用结构之前初始化通道和映射。
1赞 Cerise Limón 2/7/2022
是的,该功能有效。此功能也有效:.要理解的关键点是,地图和通道在内部是一个指针。指针可以被复制,但仍引用通道或地图的数据。func AddToMap(cs CustomStruct){ cs.Storage["foo"]="foo" }

答:

2赞 jch 2/7/2022 #1

切片、映射和通道是 Go 中类似指针的值:复制包含通道的结构会复制对通道的引用,而不是通道本身:

a := CustomStrct{
    RetrieveChannel: make(chan Request),
}
b := a
log.Println(a.RetrieveChannel == b.RetrieveChannel)    // logs true

因此,通过值或引用传递结构是非常好的。

如果你需要确保将标记尝试按值传递你的结构,最简单的解决方案是在结构中嵌入一个:go vetsync.Mutex

type CustomStrct struct {
    mu sync.Mutex
    ...
}

您不需要实际使用互斥锁:只需将其嵌入到结构中,每当您尝试按值传递它时,都会引起抱怨。go vet