如何确保由通道和映射组成的结构以引用方式传递?

huangapple go评论80阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2022年2月7日 03:15:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/71010776.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定