英文:
A new slice has nil as it's 1st value
问题
我正在尝试在Golang中创建一个简单的图像调整大小服务器的概念验证。我对golang还不熟悉,在这个令人沮丧的问题上卡住了。也许我没有正确理解切片的用法,所以请告诉我在使用切片时哪里出错了。
我使用request.ParseMultipartForm()
来解析发送到服务器的文件和任何POST参数。然后,我需要将文件列表(类型为map[string][]*multipart.FileHeader
)转换为io.Reader
的列表。我使用以下代码来实现。
// 将FileHeader映射转换为io.Reader列表
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)
}
我的问题是,由于某种原因,在使用make
初始化后,images
的第一个值变成了nil
。我知道这是因为fmt.Println(images)
(第2行代码)输出了:
[<nil>]
我原以为make
会返回一个长度为零的切片。如果我改为使用make([]io.Reader, 0)
,它会按照我期望的工作。我对这种行为感到困惑,希望能得到解释。
英文:
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\n", 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.
答案1
得分: 4
images := make([]io.Reader, len(reqForm.File))
创建了一个长度和容量相同的切片。当你后续使用append
函数时,新的值会被放在切片的末尾。
你可以通过两种方式来修复这个问题:
- 使用长度为0,但容量为
len(reqForm.File)
的方式来创建切片:images := make([]io.Reader, 0, len(reqForm.File))
。 - 使用空切片开始,并允许
append
函数自然地扩展切片:var images []io.Reader
。
我会选择后者,因为它稍微简单一些,并且如果后续发现这是一个瓶颈,可以将其替换为预分配的切片。
英文:
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:
- start with a length 0, but the given capacity with
images := make([]io.Reader, 0, len(reqForm.File))
- start with an empty slice, and allow
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.
答案2
得分: 0
使用初始长度为零。例如,
images := make([]io.Reader, 0, len(reqForm.File))
> Go编程语言规范
>
> 创建切片、映射和通道
>
> 调用 类型 T 结果
>
> make(T, n) 切片 长度为 n,容量为 n 的类型为 T 的切片
> make(T, n, m) 切片 长度为 n,容量为 m 的类型为 T 的切片
英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论