
go语言中数组是值类型,直接传递会复制整个底层数组;若需类似c的“传址”效果,应使用切片(slice),因其底层包含指向底层数组的指针、长度和容量,天然具备引用语义。
go语言中数组是值类型,直接传递会复制整个底层数组;若需类似c的“传址”效果,应使用切片(slice),因其底层包含指向底层数组的指针、长度和容量,天然具备引用语义。
在Go中,数组(如 [100]int)是固定长度、值语义的类型:每次作为参数传递时,整个数组内容会被完整复制——这不仅低效,也与C语言中“数组名退化为指针”的行为截然不同。因此,你遇到的错误:
cannot use a (type [100]int) as type *int in argument to f
本质上是因为函数期望接收一个指向单个 int 的指针(*int),而你传入的是一个长度为100的数组值([100]int),二者类型完全不兼容。
✅ 正确做法:使用切片(slice)
切片是Go中更常用、更灵活的序列抽象,其结构为:
type slice struct {
array unsafe.Pointer // 指向底层数组首地址
len int // 当前长度
cap int // 容量上限
}
正因包含指针字段,切片本身虽是值类型(拷贝开销小),但其数据操作天然作用于共享的底层数组——即具备“引用语义”。
以下为推荐实现:
package main
import "fmt"
func f(a []int) {
fmt.Println(a[1]) // 直接访问索引1,无需解引用
}
func main() {
// 创建长度为2、容量为100的切片(满足访问a[1]的需求)
a := make([]int, 2, 100)
a[1] = 100
f(a) // ✅ 传递切片,安全且高效
}
⚠️ 注意事项:
- 切片的 len 必须 ≥ 访问索引(如 a[1] 要求 len(a) >= 2),否则运行时 panic:index out of range;
- 若确实需要操作固定大小的底层数组(如与C互操作或内存布局敏感场景),可传递数组指针,例如 func f(a *[100]int),但此时调用需显式取地址:f(&a);
- 切片修改元素会影响原底层数组,但追加(append)可能触发扩容并导致底层数组更换——此时原切片与新切片不再共享数据,需注意副作用。
总结:Go鼓励使用切片而非数组进行常规数据传递;它兼顾安全性、性能与表达力,是符合Go惯用法(idiomatic Go)的最佳实践。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











