package main
import (
"fmt"
)
func main() {
var ms [][]string
test(ms)
fmt.Println(ms)
}
func test(ms [][]string) {
m := []string{"hello", "world"}
ms = append(ms, m)
}
为什么最终ms没有增长
package main
import (
"fmt"
)
func main() {
var ms [][]string
test(ms)
fmt.Println(ms)
}
func test(ms [][]string) {
m := []string{"hello", "world"}
ms = append(ms, m)
}
为什么最终ms没有增长
如果需要改变传入的参数的值,需要传入指针。
func main() {
var ms [][]string
test(&ms)
fmt.Println(ms)
}
func test(ms *[][]string) {
m := []string{"hello", "world"}
*ms = append(*ms, m)
}
7 回答5.6k 阅读
6 回答7.1k 阅读✓ 已解决
4 回答2.6k 阅读
2 回答1.1k 阅读✓ 已解决
1 回答2.3k 阅读
2 回答1.1k 阅读
1 回答1.1k 阅读
确切的说, Go中的切片不是引用(不是C++中的那种引用)。
这段代码在我的机器上的输出:
可以明显看出:
test函数中
ms
的地址和main函数中ms
的地址一样
。test函数中
&ms
的地址和main函数中&ms
的地址不一样
。append之前和append之后, test函数中
ms
的地址不一样
。append之前和append之后, test函数中
&ms
的地址一样
。append之后, main函数中
ms
和&ms
的地址都没有变化
。再结合第三条输出:
ms
输出的地址&ms[0]输出的地址一样, 但是与&ms
输出的地址不一样。我们知道
&
是取地址符,所以可以得出结论:test函数中的ms和main函数中的ms不是一个变量,但是它们指向同一个地址。
ms
变量里存储了它这个二维字符串数组的第一个元素的地址(实际上还存储了其他的信息)。append
函数的官方文档同时也说了,如果slice中没有足够的容量,则会重新分配内存并返回。所以在
ms = append(ms, m)
返回了一个新的地址,并把这个地址赋值给了ms,也就导致ms变量里存储的第一个元素的地址发生了改变。