go函数声明严格:func与左括号须同行,参数及返回值类型不可省略;首字母大写决定导出性;无默认参数或命名参数;闭包捕获变量引用而非值。

Go 里没有“函数定义”,只有 func 声明——漏写类型、少括号、换行错位,编译器立刻报错,不给你任何商量余地。
func 后不能换行,参数和返回值类型一个都不能省
很多人从 Python 或 JS 转来,习惯写成:
func add<br> (a, b int)<br> int {<br> return a + b<br>}
这在 Go 里非法:func 关键字和左括号 ( 必须在同一行(除非用括号包裹多行参数,但极少用)。更关键的是,类型声明不能省略:
-
func add(a, b) int❌ 缺少参数类型,报missing type in function argument -
func add(a, b int) {}❌ 空返回必须写(),否则报missing return type -
func add(a, b int) int✅ 正确:两个int参数,一个int返回值 -
func split(n int) (int, int)✅ 多返回值必须用括号包裹
首字母大小写决定能不能被其他包调用
Go 没有 public/private 关键字,导出性全靠函数名首字母:
-
func DoWork()✅ 其他包可导入后调用mypkg.DoWork() -
func doWork()✅ 合法,但仅限当前包内使用;外部包写mypkg.doWork()直接报undefined: mypkg.doWork - 测试文件
*_test.go可以访问小写函数,但生产代码跨包调用时别指望它能“通”
传参顺序和类型严格匹配,不支持默认值或命名参数
Go 不会帮你转换、重排、补缺。声明是 func connect(host string, port int) error,那调用就只能是:
-
connect("localhost", 8080)✅ -
connect(8080, "localhost")❌ 报cannot use int as string -
connect("localhost")❌ 报not enough arguments -
connect("localhost", "8080")❌ 报cannot use string as int
想模拟可选参数?老实用结构体:
type Config struct {<br> Host string<br> Port int<br> Timeout time.Duration<br>}<br>func connect(cfg Config) error { ... }<br>// 调用:<br>connect(Config{Host: "x", Port: 8080})
闭包捕获的是变量引用,不是循环当时的值
这是并发场景下最隐蔽的坑之一:
for i := 0; i go func() {<br> fmt.Println(i)<br> }()<br>}
大概率输出三个 3,因为所有 goroutine 共享同一个变量 i,等它们真正执行时,循环早已结束,i 已是终值。
- 修复方式一(推荐):把当前值作为参数传入匿名函数
go func(n int) { fmt.Println(n) }(i) - 修复方式二:在循环内声明新变量绑定当前值
val := i; go func() { fmt.Println(val) }() - 注意:如果闭包里修改了外层变量,又没加锁,多个 goroutine 并发写就是未定义行为
函数签名一旦暴露给其他包,改参数名、增删参数、调整返回值顺序——全是破坏性变更。Go 没有函数重载,也没版本化函数名机制,所以第一次写对,比后期修更重要。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











