
go 中数组是值类型,直接传递会复制整个底层数组;若需类似 c 的引用传递效果,应使用切片(slice),因其底层包含指向底层数组的指针、长度和容量,天然支持“引用式”操作。
go 中数组是值类型,直接传递会复制整个底层数组;若需类似 c 的引用传递效果,应使用切片(slice),因其底层包含指向底层数组的指针、长度和容量,天然支持“引用式”操作。
在 Go 中,数组(如 [100]int)是固定长度、值语义的类型:每次作为参数传递时,整个数组都会被复制,这既低效又不符合 C 语言中 int* 的指针传递习惯。你遇到的错误:
cannot use a (type [100]int) as type *int in argument to f
正是因为 f 期望接收一个 *int(即单个整数的地址),而你传入的是一个 [100]int 类型的值——二者类型完全不兼容,Go 不允许隐式转换。
✅ 正确做法:使用 slice(切片)
切片 []int 是引用类型(更准确地说,是包含指针的描述符),它不拥有数据,而是对底层数组的视图。传递 slice 时,仅复制其三个字段(指针、len、cap),开销恒定且语义上等价于“按引用传递”。
以下是一个完整、可运行的示例:
package main
import "fmt"
func f(a []int) {
if len(a) > 1 {
fmt.Println("a[1] =", a[1])
} else {
fmt.Println("slice too short")
}
}
func main() {
// 创建长度为 2、容量为 100 的切片(底层数组实际分配 100 个 int)
a := make([]int, 2, 100)
a[1] = 100
f(a) // 输出: a[1] = 100
}
⚠️ 注意事项:
- make([]int, 2, 100) 表示:创建一个长度(len)为 2、容量(cap)为 100 的切片,因此 a[0] 和 a[1] 可安全访问,但 a[2] 会 panic(超出长度);
- 若需直接基于已有数组构造切片,也可写为:a := [100]int{}; s := a[:2];
- 切片修改元素会影响底层数组(即被调函数中对 s[i] 的赋值,在调用方可见),但修改切片本身(如 append 或重新切片)不会影响原变量,除非返回新切片并显式赋值。
? 总结:
不要试图用 *[N]int 模拟 C 风格的数组指针传递——既笨重又易错。Go 的设计哲学是“用对的工具做对的事”:需要动态长度、高效传递、共享数据?用 slice;需要固定布局、栈上存储、内存精确控制?才考虑数组。绝大多数场景下,[]T 就是你该用的“引用式数组”。











