Reputation: 2957
I have written the following code. But I can't have it compiled. Here is my code:
package main
import "fmt"
func main() {
tmp := make([]int, 10)
for i := 0; i < 10; i++ {
tmp[i] = i
}
res := mapx(foo, tmp)
fmt.Printf("%v\n", 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!
Upvotes: 10
Views: 18794
Reputation: 166559
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.
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 "fmt"
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]
Upvotes: 31