英文:
Problems about `slice` and `append` in Go
问题
我写了以下代码。但是我无法编译它。这是我的代码:
<!-- language: lang-go -->
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
}
同时错误信息也很令人困惑:
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 "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!
答案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 "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]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论