Go函数定义必须用func关键字,参数名在前类型在后,左大括号不能换行;所有参数值传递,但slice/map/ptr内部含指针故可修改原数据;函数签名严格决定类型,不支持重载。

Go 里定义函数必须用 func 关键字,参数名在前、类型在后,不能省略参数名,也不能把类型写在参数名前面(比如 func add(int a, int b) int 是非法的)。
函数定义语法和常见错误
最简形式是无参无返回值:func sayHi() {};带参带返回值则像这样:func add(a int, b int) int { return a + b }。
- 多个同类型参数可缩写为
a, b, c int,但类型一变就得单独写,比如name string, age int, active bool - 返回值类型必须显式声明;多返回值要用括号包裹,如
(int, error) - 命名返回值(如
(sum int, avg float64))支持裸return,但容易漏初始化某个变量,导致静默返回零值 - 函数体左大括号
{不能换行,否则编译报错:unexpected newline
调用时必须处理所有返回值
Go 强制你明确接收或忽略每个返回值,os.Open("x.txt") 不能只写 f := os.Open("x.txt"),会报错 multiple-value os.Open() in single-value context。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 正确写法是两个变量接收:
f, err := os.Open("x.txt") - 只关心错误?用下划线忽略:
_, err := os.Open("x.txt") - 顺序不能颠倒:写成
err, f := os.Open("x.txt")会导致err被赋成*os.File类型,编译失败 - 不推荐
_, _ := someFunc(),除非你真不需要任何返回值
值传递 vs “看起来像引用”
Go 所有参数都是值传递,但 []int、map[string]int、*T 这些类型内部含指针,所以修改元素会影响原数据——但这不是引用传递,只是底层共享。
立即学习“go语言免费学习笔记(深入)”;
- 传
[]int进函数,改s[0] = 99会影响外部;但若在函数内做s = append(s, 1)且扩容了,新 slice 就不会影响调用方 - 想确保增删操作生效,得把新 slice 返回并重新赋值:
s = myAppend(s, 1) - 传
*Person是最稳妥的修改方式,但要注意 nil 指针解引用会 panic - 纯值类型(如
int、string、普通struct{})传进去改,对外完全没影响
最容易被忽略的是:函数签名(参数类型+返回类型)严格决定函数类型,哪怕名字一样、逻辑一样,只要签名不同就是不同类型;而包内不能有两个同名函数,连重载都不支持——这点在封装工具函数时特别容易踩坑。

















