一个新的切片的第一个值是nil。

huangapple go评论80阅读模式
英文:

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(&quot;Converting: %v\n&quot;, 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:

[&lt;nil&gt;]

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

huangapple
  • 本文由 发表于 2014年7月27日 01:03:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/24973429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定