I'm trying to create a simple proof-of-concept for an image resizing server in Golang. I'm new to golang, and am stuck at this frustrating issue. Maybe I haven't understood slices correctly, so please let me where I am wrong in the usage of slices.
I use request.ParseMultipartForm()
to parse the files and any POST params sent to the server. Then, I need to convert the list of files (which are a map[string][]*multipart.FileHeader
). I'm using the following code to do so.
// 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
", f)
if err != nil {
writeErrorToResponse(resp, err)
return
}
images = append(images, f)
}
My problem is, for some reason images
ends up having a nil
as it's first value after being initialized by make
. I know this because the fmt.Println(images)
(line of code 2) prints out:
[<nil>]
I assumed that the make would return a slice with zero elements. If I do a make([]io.Reader, 0)
instead, it works as I expect. I'm confused with this behavior and an explanation would be very helpful.
images := make([]io.Reader, len(reqForm.File))
creates a slice of the given length and the same capacity. When you later append
to it, new values are put on the end.
You can fix this in two ways:
images := make([]io.Reader, 0, len(reqForm.File))
append
to grow it naturally. var images []io.Reader
.I'd choose the latter since it's slightly simpler, and replace it with the preallocated slice later if it turns out it's a bottleneck.
Use an initial length of zero. For example,
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