Go函数作为参数需显式类型匹配,形参名无关但签名必须完全一致;可传具名函数、绑定方法、匿名函数或闭包;函数值是可比较的值类型,不可取地址,nil需判空,同签名不同别名类型不兼容。

Go 语言中函数可以像变量一样直接作为参数传入,但必须显式声明类型匹配——类型不一致会编译失败,不是靠名字或运行时反射。
函数类型声明必须严格匹配 func(int, int) int
传函数前,接收方函数签名里得写清楚形参和返回值的完整类型。比如 func(a, b int) int 和 func(x, y int) int 是等价的(参数名无关),但 func(int, int) string 或 func(int) int 就不兼容。
- 类型声明写在参数位置,例如:
func doMath(a, b int, op func(int, int) int) int - 调用时传函数名即可,不用加括号:
doMath(10, 3, add),不是doMath(10, 3, add()) - 如果函数带 receiver(即方法),需绑定实例后传,例如:
obj.calc,不能直接传(*MyType).calc
匿名函数可直接作为实参传入 func(x int) bool
不需要提前定义具名函数,临时逻辑可写成字面量形式。常见于过滤、转换等场景,比如 sort.Slice 的比较函数。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 语法是:
func(参数列表) 返回类型 { 函数体 },后面紧跟括号表示立即调用;不加括号才是传函数值 - 闭包能捕获外部变量,但要注意生命周期:别把栈上局部变量的地址逃逸出去
- 示例:
apply([]int{1,2,3}, func(x int) int { return x * x })
传函数时容易忽略指针与值语义的混淆
函数本身是值类型,传的是函数指针(底层实现),所以复制开销极小。但开发者常误以为“传函数”和“传结构体”一样需要考虑拷贝成本——其实完全不用。
立即学习“go语言免费学习笔记(深入)”;
- 函数值可比较(
==),两个同地址函数值相等;但不可用==比较匿名函数,因为每次定义都是新值 - 不要对函数值取地址:
&myFunc是非法操作,编译报错cannot take the address of myFunc - nil 函数值合法,调用前应判空:
if f != nil { f() },否则 panic
最易被忽略的一点:函数类型是独立类型,哪怕签名相同,不同地方定义的 type A func(int) int 和 type B func(int) int 也不兼容,不能互相赋值或传参——必须用同一个类型别名或原生函数字面量类型。

















