关于Go语言中的`slice`和`append`的问题

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

Problems about `slice` and `append` in Go

问题

我写了以下代码。但是我无法编译它。这是我的代码:

<!-- language: lang-go -->

package main

import &quot;fmt&quot;

func main() {
	tmp := make([]int, 10)
	for i := 0; i &lt; 10; i++ {
		tmp[i] = i
	}
	res := mapx(foo, tmp)
	fmt.Printf(&quot;%v\n&quot;, res)
}

func foo(a int) int {
	return a + 10
}

func mapx(functionx func(int) int, list []int) (res []int) {
	res = make([]int, 10)
	for _, i := range(list) {
		append(res, functionx(i))
	}
	return
}

同时错误信息也很令人困惑:
prog.go:21: append(res, functionx(i)) not used

但是如果我将append(res, functionx(i))(第21行)替换为res = append(res, functionx(i)),它就能正常工作。有人可以帮助我吗?

谢谢!

英文:

I have written the following code. But I can't have it compiled. Here is my code:

<!-- language: lang-go -->

package main

import &quot;fmt&quot;

func main() {
	tmp := make([]int, 10)
	for i := 0; i &lt; 10; i++ {
		tmp[i] = i
	}
	res := mapx(foo, tmp)
	fmt.Printf(&quot;%v\n&quot;, res)
}

func foo(a int) int {
	return a + 10
}

func mapx(functionx func(int) int, list []int) (res []int) {
	res = make([]int, 10)
	for _, i := range(list) {
		append(res, functionx(i))
	}
	return
}

Meanwhile the error message is also very confusing:
prog.go:21: append(res, functionx(i)) not used

But if I replace append(res, functionx(i))(line 21) with res = append(res, functionx(i)), it works quite well. Can anybody help me?

Thank you!

答案1

得分: 31

> 追加和复制切片
>
> 可变参数函数append将零个或多个值x追加到类型为S的切片s中,并返回结果切片,也是类型S。
>
> 如果s的容量不足以容纳额外的值,append会分配一个新的足够大的切片,该切片同时适应现有的切片元素和额外的值。因此,返回的切片可能引用不同的底层数组。
>
> 函数调用
>
> 在函数调用中,函数值和参数按照通常的顺序进行求值。在它们求值之后,调用的参数按值传递给函数,并且被调用的函数开始执行。函数的返回参数在函数返回时按值传递回调用函数。

在Go语言中,参数是按值传递的。

你需要写成res = append(res, functionx(i)),这样你就不会丢弃res的新值,它引用了一个不同的切片,可能也引用了一个不同的底层数组。

例如:

package main

import "fmt"

func main() {
    res := []int{0, 1}
    fmt.Println(res)
    _ = append(res, 2) // 丢弃
    fmt.Println(res)
    res = append(res, 2) // 保留
    fmt.Println(res)
}

输出:

[0 1]
[0 1]
[0 1 2]
英文:

> Appending to and copying slices
>
> The variadic function append appends zero or more values x to s of
> type S, which must be a slice type, and returns the resulting slice,
> also of type S.
>
> If the capacity of s is not large enough to fit the additional values,
> append allocates a new, sufficiently large slice that fits both the
> existing slice elements and the additional values. Thus, the returned
> slice may refer to a different underlying array.
>
> Calls
>
> In a function call, the function value and arguments are evaluated in
> the usual order. After they are evaluated, the parameters of the call
> are passed by value to the function and the called function begins
> execution. The return parameters of the function are passed by value
> back to the calling function when the function returns.

In Go, arguments are passed by value.

You need to write res = append(res, functionx(i)) so that you don't discard the new value for res, which refers to a different slice and, possibly, a different underlying array.

For example,

package main

import &quot;fmt&quot;

func main() {
	res := []int{0, 1}
	fmt.Println(res)
	_ = append(res, 2) // discard
	fmt.Println(res)
	res = append(res, 2) // keep
	fmt.Println(res)
}

Output:

[0 1]
[0 1]
[0 1 2]

huangapple
  • 本文由 发表于 2012年5月24日 23:04:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/10740153.html
匿名

发表评论

匿名网友

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

确定