Pointers Go:将数组指针传递到gob而不复制?
我有一个非常非常大的映射数组(不是切片),然后我尝试对其进行编码。我真的需要避免复制数组,但我不知道该怎么做 到目前为止,我有:Pointers Go:将数组指针传递到gob而不复制?,pointers,go,Pointers,Go,我有一个非常非常大的映射数组(不是切片),然后我尝试对其进行编码。我真的需要避免复制数组,但我不知道该怎么做 到目前为止,我有: func doSomething() { var mygiantvar [5]map[string]Searcher mygiantvar = Load() Save(`file.gob.gz`, &mygiantvar) } func Save(filename string, variable *[5]map[string]Searcher) er
func doSomething() {
var mygiantvar [5]map[string]Searcher
mygiantvar = Load()
Save(`file.gob.gz`, &mygiantvar)
}
func Save(filename string, variable *[5]map[string]Searcher) error {
// Open file for writing
fi, err := os.Create(filename)
if err !=nil {
return err
}
defer fi.Close()
// Attach gzip writer
fz := gzip.NewWriter(fi)
defer fz.Close()
// Push from the gob encoder
encoder := gob.NewEncoder(fz)
err = encoder.Encode(*variable)
if err !=nil {
return err
}
return nil
}
据我所知,这将传递mygiantvar的指针进行保存,从而保存第一个副本。但是整个数组肯定会被复制到encoder.Encode
中,然后它会复制到更多的函数中,对吗
这个mygiantvar
变量的大小大约为10GB。因此,它必须避免被复制
但是,也许只有实际的数组[5]部分被复制,但其中的映射是数组中的指针,所以指向映射的指针数组将被复制,而不是映射本身?我对此一无所知——这一切都很令人困惑
有什么想法吗?注意,它将在接口{}
中传递
func (enc *Encoder) Encode(v interface{}) error {
这意味着一种指向您将传递给它的任何内容的指针,正如我在“(另见“) 接口值不是具体结构的值(因为它的大小是可变的,这是不可能的),而是一种指针(更准确地说是指向结构的指针和指向类型的指针) 这意味着它不会复制地图(或此处的)的全部内容。
因为数组是一个值,所以可以在调用
Encode()
期间对其进行切片以避免任何复制:
见“
这也是创建给定数组的切片的语法:
如果这不起作用,您可以保留*变量
(这里是一个数组:[5]映射[字符串]搜索器
),因为映射类型是引用类型,就像指针或切片一样:副本不会很大。见“” 当数组传递到
接口{}
时,将复制该数组,但不会复制映射内容。请参见此示例: 输出:
[map[test:-1]]
但是数组本身被复制了一次,它说
encoder.Encode(*variable)
?@Alasdair是的,但是你可以对它进行切片以避免复制:*variable[:]
,但是如果我对它进行切片,那么它将是一种不同的类型,肯定不会加载回定义为[5]map[string]Searcher
的结构中?我希望即使复制了数组,也不会复制数组中的贴图,只复制它们的指针。@Alasdair你是对的,我编辑了答案:不会复制贴图内容。只有映射本身,它是一种引用类型。接口可能包含指针,但它是指向新分配的内存的指针,该内存包含值本身,并且该内存通过复制该值来初始化。因此,在他的数组中,它会为数组的大小分配空间,复制内容,然后在接口中放置指向新内存的指针。要证明接口不仅仅是通过引用传递的,请参见以下内容。
x := [3]string{"Лайка", "Белка", "Стрелка"}
s := x[:] // a slice referencing the storage of x
package main
import "fmt"
func main() {
var a [1]map[string]int
a[0] = make(map[string]int)
a[0]["test"] = 0
modify(a)
fmt.Println(a)
}
func modify(arr interface{}) {
a := arr.([1]map[string]int)
a[0]["test"] = -1
}
[map[test:-1]]