【问题标题】:Does slice assignment in Go copy memoryGo中的切片分配是否复制内存
【发布时间】:2019-08-09 05:21:35
【问题描述】:

目的:我有一个大缓冲区,我希望有一个指针数组/切片指向缓冲区中的不同位置。

我在做什么:

datPtrs := make([][]byte, n)
for i:=0; i<n; i++{
    datPtrs[i] = bigBuf[i*m:(i+1)*m]
}

我的问题:

  1. 这会复制内存吗?我的猜测不是,但我找不到任何地方来证实这一点。
  2. 找出是否存在内存副本的最佳方法/工具是什么?

【问题讨论】:

  • 第二个问题的答案不完整:如果您有some test code,,您可以通过将新信息写入其中一个值来凭经验验证此类事情;如果它影响了另一个,那么你有一个新的引用而不是原始内存的副本。
  • 您在哪里寻找有关此主题的信息?我确信这个确切的主题记录得很好。你至少应该阅读介绍和有效的 go 文档,两者都可以在 golang.org 获得。
  • 第二个问题的技术答案:一切都是复制品,你只需要知道你在复制的什么。在切片、映射、指针和接口的情况下,它是一个被复制的指针。
  • 谢谢大家,信息真的很有帮助!

标签: go


【解决方案1】:

Go 切片被实现为结构体:

src/runtime/slice.go:

type slice struct {
    array unsafe.Pointer
    len   int
    cap   int
}

您正在分配/复制切片结构,它不复制底层数组,只复制它的指针。


一个简单的例子:

package main

import (
    "fmt"
)

func main() {
    buf := make([]byte, 8)
    for i := range buf {
        buf[i] = byte(i)
    }
    sub := buf[1:3]
    fmt.Println(buf)
    fmt.Println(sub)
    for i := range sub {
        sub[i] += 43
    }
    fmt.Println(buf)
    fmt.Println(sub)
}

游乐场:https://play.golang.org/p/4OzPwuNmUlY

输出:

[0 1 2 3 4 5 6 7]
[1 2]
[0 44 45 3 4 5 6 7]
[44 45]

The Go Blog: Go Slices: usage and internals

【讨论】:

    【解决方案2】:
    1. 没有

    Slice 只是一个指向内存的指针 + lencap
    见:Why can not I duplicate a slice with `copy()` in Golang?


    1. 像这样:
    package main
    
    import (
        "fmt"
    )
    
    func main() {
        bigBuf := []byte{1, 2, 3, 4, 5}
    
        datPtrs := make([][]byte, 2)
        for i := 0; i < 2; i++ {
            datPtrs[i] = bigBuf[i : i+1]
        }
        fmt.Println(bigBuf) // [1 2 3 4 5]
        datPtrs[0][0] = 10
        fmt.Println(bigBuf) // [10 2 3 4 5]
    
        datPtrs[1][0] = 20
        fmt.Println(bigBuf) // [10 20 3 4 5]
    }
    
    

    【讨论】:

    • 谢谢!这真的很有帮助!
    猜你喜欢
    • 2018-07-15
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 2022-01-25
    • 1970-01-01
    • 2016-05-12
    • 2016-03-04
    • 2016-09-26
    相关资源
    最近更新 更多