【问题标题】:A new slice has nil as it's 1st value新切片的第一个值为零
【发布时间】:2014-07-26 17:03:16
【问题描述】:

我正在尝试为 Golang 中的图像大小调整服务器创建一个简单的概念验证。我是 golang 的新手,并且陷入了这个令人沮丧的问题。可能我没有正确理解切片,所以请告诉我我在切片使用方面的错误之处。

我使用request.ParseMultipartForm() 来解析文件和发送到服务器的任何 POST 参数。然后,我需要转换文件列表(这是一个map[string][]*multipart.FileHeader)。我正在使用以下代码来执行此操作。

    // convert the FileHeader map to a list of io.Readers
    images := make([]io.Reader, len(reqForm.File))
    fmt.Println(images)
    for _, fileHeaders := range reqForm.File {
        fh := fileHeaders[0]
        f, err := fh.Open()
        fmt.Printf("Converting: %v\n", f)
        if err != nil {
            writeErrorToResponse(resp, err)
            return
        }

        images = append(images, f)
    }

我的问题是,由于某种原因,images 在被make 初始化后,最终将nil 作为它的第一个值。我知道这是因为 fmt.Println(images)(代码 2 行)打印出来:

[<nil>]

我假设 make 会返回一个包含零元素的切片。如果我改为使用make([]io.Reader, 0),它会按我的预期工作。我对这种行为感到困惑,解释一下会很有帮助。

【问题讨论】:

  • 什么是 POC?你的意思是概念证明吗?请尽量避免使用模棱两可的首字母缩略词。

标签: go


【解决方案1】:

images := make([]io.Reader, len(reqForm.File)) 创建一个给定长度和相同容量的切片。当您稍后append 时,会将新值放在末尾。

您可以通过两种方式解决此问题:

  • 以长度0开头,但给定容量以images := make([]io.Reader, 0, len(reqForm.File))
  • 从一个空切片开始,让append 自然生长。 var images []io.Reader

我会选择后者,因为它稍微简单一些,如果后来发现这是一个瓶颈,则将其替换为预先分配的切片。

【讨论】:

  • 非常感谢。我猜来自 Python,我假设带有 1 个元素的新切片仍然是空的,并且附加到它会覆盖 nil 值。
  • 如果您已经知道为什么浪费内存的大小,我不得不不同意选择不封顶的切片。
【解决方案2】:

使用初始长度为零。例如,

images := make([]io.Reader, 0, len(reqForm.File))

The Go Programming Language Specification

Making slices, maps and channels

Call             Type T     Result

make(T, n)       slice      slice of type T with length n and capacity n
make(T, n, m)    slice      slice of type T with length n and capacity m

【讨论】:

    猜你喜欢
    • 2015-08-28
    • 1970-01-01
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    • 2021-02-11
    • 2023-01-08
    • 1970-01-01
    • 2023-02-25
    相关资源
    最近更新 更多