go语言基础语法有三大易错点:一是:=仅限函数内使用,包级作用域须用var/const;二是var声明类型必须在变量名后;三是切片扩容可能共享底层数组,需显式复制隔离。

为什么 := 在包级作用域会编译失败
因为 := 是短变量声明,它隐含“新变量声明 + 初始化”两件事,而 Go 要求包级变量必须用 var 显式声明。直接写 name := "go" 在函数外,编译器会报 syntax error: non-declaration statement outside function body。
-
:=只能在函数内部使用;包级、全局作用域只能用var或const - 重复使用
:=声明已存在的变量名(比如x := 1后再x := 2),会触发no new variables on left side of := - 多变量同时声明时,只要其中有一个是新变量,整行就能用
:=,例如a, b := 1, "hello"中a已存在但b是新的,也合法
var 声明时类型放右边是硬性约定
Go 把类型写在变量名之后,比如 var count int,不是 int count。这不是风格问题,是语法强制——写反了直接语法错误。这个设计让类型推导更自然,也统一了数组、切片、函数等复杂类型的声明顺序。
- 初始化时可省略类型:
var msg = "hello"→ 编译器推导为string - 批量声明必须对齐类型或值:
var (a int; b string; c = 3.14),混合写法允许,但不能漏掉分号或换行错位 - 包级变量若未初始化,会自动设为对应类型的零值(
int是0,string是"",map是nil)
切片扩容后为什么有时还共享底层数组
切片是引用类型,底层指向数组。用 append 追加元素时,如果容量足够,就原地修改;一旦超出容量,就会分配新数组、拷贝旧数据、返回新切片——但旧切片变量仍指向原底层数组,这点极易引发意外数据覆盖。
- 判断是否扩容:打印
cap(s)和len(s),追加前后对比;扩容后cap通常翻倍(小 slice)或增长 1.25 倍(大 slice) - 想彻底隔离内存?显式复制:
newSlice := append([]int(nil), oldSlice...)或copy(newSlice, oldSlice) - 常见陷阱:多个 goroutine 并发操作同一底层数组的切片,即使各自变量不同,也可能踩到同一块内存
main 函数必须在 package main 且不能重复
Go 编译器把 package main 当作可执行程序入口,一个目录下只允许一个 func main()。否则报错 main redeclared in this block,不是警告,是编译失败。
- 多个可执行程序?拆到不同子目录,比如
cmd/api/main.go和cmd/cli/main.go,再分别go run ./cmd/api -
go run main.go可绕过目录限制,因为它只编译当前文件,但该文件里所有依赖必须在同一目录下,不适合工程化项目 - 别把
main放进utils或pkg目录——那些应是package utils,否则 import 会出错
:= 位置、切片共享、main 冲突上,几乎是标配。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











