那天,数组小姐鼓起勇气对函数先生说:“我想进入你的世界。”
函数先生温柔地回答:“欢迎,但有个规矩——你得完整复制一个自己才能进来。”
数组小姐看着自己庞大的身躯,欲哭无泪:“这...这也太不环保了吧!”
第一章:初遇数组参数 — 一场内存的“奢侈消费”
作为一个刚从Python或JavaScript转来的Gopher,你可能会习惯性地写出这样的代码:
func main() {
scores := [5]int{90, 85, 78, 92, 88}
printScores(scores) // 看似普通的函数调用
fmt.Println("原数组:", scores) // {90, 85, 78, 92, 88}
}
func printScores(arr [5]int) {
fmt.Println("函数内数组:", arr)
// 这里修改arr不会影响外面的scores
}
表面风平浪静,背后却发生了一场“内存大迁徙”。
重点来了:在Go里,当你把数组作为参数传递给函数时,发生的是值拷贝(value copy),不是引用传递!
什么意思?让我用个更直观的例子:
func main() {
// 假设这是个装满珍贵数据的数组
bigData := [1000000]int{}
for i := range bigData {
bigData[i] = i
}
processArray(bigData) // 危险操作!
}
func processArray(data [1000000]int) {
// 就为了这个简单的打印...
fmt.Println("数组长度:", len(data))
}
你发现痛点了吗?为了一个简单的函数调用,Go在背后默默复制了1000000个整数!这好比你要看朋友的照片,他非要把自家整个相册连柜子都搬过来给你。
第二章:解剖值拷贝 — 数组的“分身术”
为了真正理解发生了什么,我们来看看内存布局:
原始数组scores (main函数中)
内存地址: 0x1000 → [90, 85, 78, 92, 88]
当调用printScores(scores)时:
Go会创建副本,假设新地址: 0x2000 → [90, 85, 78, 92, 88]
用代码验证一下:
package main
import "fmt"
func main() {
arr := [3]int{1, 2, 3}
fmt.Printf("原数组地址: %p\n", &arr) // 比如: 0xc000018240
checkAddress(arr)
}
func checkAddress(copyArr [3]int) {
fmt.Printf("副本数组地址: %p\n

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



