读入一个结构会覆盖另一个

时间:2018-09-07 06:55:52

标签: go struct

我在Go中管理结构存在一些问题。我有复杂的结构和基于该结构的两个变量-“上一个”和“当前”。我正在尝试从tarfile中读取数据,进行一些计算并将当前的内容替换为以前的内容。 但是在我读到当前版本时,在下一次阅读迭代中,似乎覆盖了“上一个”的内容,并且两个变量都相同。 结构定义如下:

type Mystruct struct {
    Data       [][]sql.NullString
    Rnames     []string
    Nsize      int
    Msize      int
    Namemaxlen map[string]int
    Valid      bool
    Err        error
}

变量不是指针。复制直接执行:上一个=当前。

tr := tar.NewReader(f)
var prev, curr Mystruct

for {
    hdr, err := tr.Next()
    if err == io.EOF {
        break
    } else if err != nil {
        log.Panicln(err)
    }

    data := make([]byte, hdr.Size)
    if _, err := io.ReadFull(tr, data); err != nil {
        log.Panicln(err)
    }

    if err = json.Unmarshal(data, &curr); err != nil {
        log.Panicln(err)
    }

    if prev.Valid != true {
        prev = curr
        continue
    }

    // other computations here

    prev = curr
}

我在哪里错?预先感谢。

1 个答案:

答案 0 :(得分:0)

问题是您的结构包含片,这些片基本上是指向内存的指针。复制这些指针意味着您的副本将作为原始指针指向SAME存储器,因此它们共享切片值。改变一个会改变另一个。

这里是a small example来说明问题:

package main

import "fmt"

type s struct {
    a     int
    slice []int
}

func main() {
    // create the original thing
    prev := s{
        a:     5,
        slice: []int{1, 2, 3},
    }
    // copy the thing into cur
    cur := prev
    // now change cur, changing a will change only cur.a because integers are
    // really copied
    cur.a = 6
    // changing the copied slice will actually change the original as well 
    // because copying a slice basically copies the pointer to memory and the
    // copy points to the same underlying memory area as the original
    cur.slice[0] = 999
    // printing both, we can see that the int a was changed only in the copy but
    // the slice has changed in both variables, because it references the same
    // memory
    fmt.Println(prev)
    fmt.Println(cur)
}