英文:
How to ensure that a Struct that is made up of channels and map gets passed by reference?
问题
我有一个包含通道和用于存储数据的映射的结构体。我想能够将该结构体传递给函数,以便利用这些通道,一旦它们被触发/有传入消息,就可以使用它们来更新与之关联的映射。
我知道当将映射默认传递给各种函数时,它们是按引用传递的。即使它们包含在自定义结构体中,这种情况是否相同呢?我如何确保整个结构体通过引用传递给函数,以便更新Storage并利用其通道?
以下是我为初始化结构体的新实例创建的构造函数:
type CustomStruct struct {
Storage map[string]string
RetrieveChannel chan string
InsertChannel chan string
}
func InitializeNewStore() CustomStruct {
newCustomStruct := CustomStruct{
Storage: make(map[string]string),
RetrieveChannel: make(chan string),
InsertChannel: make(chan string),
}
return newCustomStruct
}
英文:
I have the following struct that contains channels and a map for storage of data. I want to be able to pass that struct into functions in order to make use of those channels so that once they are triggered/have incoming messages, to use them in order to update the map that is associated with it.
I understand that maps by default are passed by reference when sent to various functions. Would this be the same case even when they are contained within a custom struct? How do i make sure that my entire struct is passed around to functions by reference in order to update Storage and also make use of its channels?
type CustomStrct struct {
Storage map[string]string
RetrieveChannel chan string
InsertChannel chan string
}
This is a constructor I have created for initialising a new instance of the struct:
func InitializeNewStore() CustomStrct {
newCustomStruct := CustomStrct {
Storage: make(map[string]string),
RetrieveChannel: make(chan Request),
InsertChannel: make(chan Request),
}
return newCustomStruct
}
答案1
得分: 2
切片(Slices)、映射(Maps)和通道(Channels)在Go语言中是类似指针的值:复制包含通道的结构体会复制对通道的引用,而不是通道本身:
a := CustomStrct{
RetrieveChannel: make(chan Request),
}
b := a
log.Println(a.RetrieveChannel == b.RetrieveChannel) // 输出 true
因此,通过值或引用传递结构体都是可以的。
如果你想确保go vet
会标记尝试通过值传递结构体的操作,最简单的解决方案是在结构体内嵌入一个sync.Mutex
:
type CustomStrct struct {
mu sync.Mutex
...
}
你不需要真正使用这个互斥锁:只要将其嵌入到结构体中,当你尝试通过值传递结构体时,go vet
就会发出警告。
英文:
Slices, maps and channels are pointer-like values in Go: copying a struct containing a channel copies a reference to the channel, not the channel itself:
a := CustomStrct{
RetrieveChannel: make(chan Request),
}
b := a
log.Println(a.RetrieveChannel == b.RetrieveChannel) // logs true
So it's quite fine to pass your struct either by value or by reference.
If you need to ensure that go vet
will flag attempts to pass your struct by value, the simplest solution is to embed a sync.Mutex
inside the struct:
type CustomStrct struct {
mu sync.Mutex
...
}
You don't need to actually use the mutex: just having it embedded in the struct will cause go vet
to complain whenever you attempt to pass it by value.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论