go函数参数名必须在类型前,多返回值须全接收或显式忽略;所有参数值传递,但slice/map/chan/*t因含指针而表现类似引用;变参...t须居末且同类型。

func 定义函数时,参数名必须在类型前,不支持 int a 这种写法;调用时多返回值必须全部接收或显式忽略,不能只取一个。
函数定义必须写参数名,且名在类型前
Go 不允许把类型放在参数名前面,func add(int a, int b) int 会直接报错:expected ')', found 'a'。这是编译器语法层面的限制,不是风格问题。
- 正确写法是
func add(a int, b int) int - 多个同类型参数可缩写:
func max(a, b, c int) int等价于分别声明 - 但一旦类型不同,就必须全写:
func openFile(path string, flag int) (*os.File, error) - 参数名不能省略(哪怕只用一次),否则函数体内无法引用;下划线
_可占位,但别滥用——它会让调用方更难理解语义
调用时多返回值必须显式处理,不能“只拿一个”
像 os.Open 返回 (*os.File, error),写成 f := os.Open("x.txt") 会编译失败。Go 强制你面对所有返回值,避免静默丢弃错误。
使用 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类型 - 命名返回值(如
func split(n int) (x, y int))支持裸return,但容易漏初始化某个变量,结果返回零值而不报错
所有参数都是值传递,但 slice/map/chan/*T 行为像“引用”
Go 没有引用传递,只有值传递。但 []int、map[string]int、chan int 和 *struct{} 这些类型,其值本身包含指针字段,复制后仍指向同一底层数据。
- 传
slice进函数并修改元素(如s[0] = 99),原 slice 会变 - 但若在函数内做
s = append(s, 1)且触发扩容,新slice就和外部无关了——因为底层数组已换 - 想确保扩容后的变更生效,得把新
slice返回并重新赋值:s = grow(s) - 传
*T最明确,但要注意 nil 指针解引用会 panic
可变参数必须放在参数列表末尾,且类型统一
...T 是唯一允许的“变参”语法,必须是最后一个参数,且所有实参类型必须和 T 一致。
- 定义:
func sum(nums ...int) int - 调用方式有两种:
sum(1, 2, 3)或sum(nums...)(注意末尾的...展开符) - 不能混用其他类型:
sum(1, "hello", 3)编译失败 - 内部把
nums当作[]int处理,可用len(nums)、range等操作
map 进去,改 key 对应的 value 会生效,但给整个 map 变量重新赋值(m = make(map[string]int))却不会影响外部——这种差异不是靠记忆,而是得看类型底层结构。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










