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]]