新切片的值为nil,因为它是第一个值

时间:2014-07-26 17:03:17

标签: go

我试图在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)
    }

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

[<nil>]

我假设make会返回一个零元素的切片。如果我改为make([]io.Reader, 0),它就像我期望的那样工作。我对此行为感到困惑,解释会非常有用。

2 个答案:

答案 0 :(得分:4)

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

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

  • 以长度0开头,但是images := make([]io.Reader, 0, len(reqForm.File))
  • 的给定容量
  • 从一个空切片开始,并允许append自然地增长它。 var images []io.Reader

我选择后者,因为它稍微简单了,如果事实证明它是一个瓶颈,那么以后用预先分配的切片替换它。

答案 1 :(得分:0)

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

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