Go 关键字 + 内置函数
25 个关键字 + 内置函数 · 点击复制
25 个关键字 + 内置函数 · 点击复制
写 Go 代码时,是 `len()` 返回长度还是 `cap()` 返回容量?`make()` 初始化 slice 时第三个参数到底传什么?翻文档翻到第 25 个关键字是 `goto`,却忘了 `defer` 的闭包陷阱。这个工具把 Go 语言 25 个关键字和 13 个内置函数按用途分类列出,每个附带可运行的代码片段和输出示例——不是死记硬背,是写代码时直接复制验证。纯浏览器运行,代码不上传服务器。
周五下午收到下周一 Go 后端岗面试通知,发现对 select 和 channel 的底层实现细节记忆模糊。把 25 个关键字和内置函数按「并发」「错误处理」「类型系统」分组快速过一遍,重点看 make、new、defer、panic 的易错点。10 分钟把高频考点在脑中过完,面试时被问到 channel 关闭后读写行为,直接答出「关闭后读会返回零值,写会 panic」。
同事提了个 PR,在循环里用 defer 关闭文件句柄,担心内存泄漏。打开工具查 defer 的「后进先出」执行时机和参数求值规则,确认循环内 defer 不会在每次迭代结束时执行,而是函数返回时才统一执行,会导致句柄堆积。在评论里附上工具截图,建议改成显式 close,避免线上 OOM。
公司新项目用 Go 重写旧 PHP 服务,第一天看代码被 chan、goroutine、interface{} 搞懵。打开工具把 25 个关键字逐个看一遍,发现 var、func、struct 和 PHP 的类似概念有对应关系,但 go、select、range 是全新思维。对照内置函数表,搞懂 len 对 slice 和 map 的行为差异,以及 append 的扩容机制,下午就能看懂同事写的并发下载模块。
线上服务凌晨告警,日志里只有一行 panic: runtime error: invalid memory address or nil pointer dereference,堆栈指向某结构体方法调用。用工具查 panic 和 recover 的配对规则:recover 必须在 defer 函数内才生效,且只能捕获当前 goroutine 的 panic。确认代码里 recover 写在主 goroutine 但 panic 发生在子 goroutine,所以没兜住。改完加个 recover 闭包,次日零告警。
刷「无重复字符的最长子串」时,想用 Go 的 map 做滑动窗口,但忘了如何声明 map 并检查 key 是否存在。打开工具看 map 的创建方式:make(map[byte]int) 和字面量 map[byte]int{} 的区别,以及 v, ok := m[key] 的惯用法。照着写完后提交,发现 len 函数对 map 返回键值对数量,正好用来算窗口长度,一次 AC。
| 输入 | 输出 | 说明 |
|---|---|---|
| break | 关键字:用于跳出循环(for、switch、select) | 常规:break 是最常用的流程控制关键字之一,覆盖循环和分支语句的典型场景 |
| make | 内置函数:创建并初始化 slice、map、channel(仅限这三种类型) | 常规:make 是 Go 中创建引用类型的关键内置函数,与 new 易混淆,需明确其专属类型 |
| defer | 关键字:延迟执行函数,在所在函数返回前按 LIFO 顺序调用 | 常规:defer 用于资源释放、锁解锁等,典型场景是文件关闭,展示其延迟与后进先出特性 |
| nil | 预声明标识符:表示指针、切片、map、channel、函数、接口的零值,无类型 | 边界:nil 不是关键字而是预声明标识符,可被重赋值,且不同类型 nil 行为不同(如 nil map 读写 panic) |
| iota | 预声明标识符:在 const 声明中自动递增的整数常量生成器,从 0 开始 | 边界:iota 只能在 const 块内使用,且每次 const 出现重置为 0,易在复杂枚举中误用 |
| new(int) | 内置函数:分配内存并返回指针 *int,值为零值 0 | 易错:new 返回指针而非值本身,与 make 混淆是常见错误;此处展示 new 对基本类型的零值分配 |
| close(ch) | 内置函数:关闭 channel ch,之后不能再发送数据,但可继续接收直到缓冲区为空 | 易错:关闭已关闭的 channel 会 panic,且向关闭的 channel 发送也 panic,需严格遵循单向关闭原则 |
| len(nil) | 内置函数:返回 0(nil slice、nil map、nil string 长度均为 0) | 边界:len 对 nil 类型不 panic,返回 0,但 cap 对 nil slice 同样返回 0,易误以为 nil 不可操作 |
1.把『break』用在 switch 外面当循环用
for i := 0; i < 10; i++ { if i == 5 { break } }for i := 0; i < 10; i++ { if i == 5 { break } } // 这是正确的,break 在 for 里break 只能终止 for、switch、select 中最内层结构。新手常误以为 break 能跳出 if 或跳出多层循环,实际只能跳一层。
2.defer 的参数在声明时求值,不是执行时
x := 1; defer fmt.Println(x); x = 2x := 1; defer func() { fmt.Println(x) }(); x = 2defer 语句的参数(包括接收器)在 defer 声明时立即求值并拷贝。闭包方式才能捕获执行时的变量值。
3.map 的零值不能直接写入
var m map[string]int; m["key"] = 1m := make(map[string]int); m["key"] = 1map 的零值是 nil,向 nil map 写入会 panic。必须用 make 或字面量初始化后才能赋值。
4.range 遍历 map 时直接修改 value 无效
m := map[string]int{"a":1}; for k, v := range m { v = 2 }m := map[string]int{"a":1}; for k, _ := range m { m[k] = 2 }range 返回的是值的拷贝,修改 v 不影响原 map。必须通过键 m[k] 来修改。
5.goroutine 中直接使用循环变量
for i := 0; i < 3; i++ { go func() { fmt.Println(i) }() }for i := 0; i < 3; i++ { go func(n int) { fmt.Println(n) }(i) }闭包捕获的是变量引用,循环结束后 i 值已变。必须通过参数传值或重新声明局部变量。
6.select 中 case 同时就绪时随机选择
select { case <-ch1: fmt.Println("ch1"); case <-ch2: fmt.Println("ch2") } // 期望 ch1 优先select { case <-ch1: fmt.Println("ch1"); default: select { case <-ch1: ...; case <-ch2: ... } }Go spec 规定多个 case 就绪时随机公平选择。如需优先级,用嵌套 select 或 default 兜底。
7.切片 append 后未重新赋值
s := []int{1,2,3}; append(s, 4); fmt.Println(s) // 输出 [1 2 3]s := []int{1,2,3}; s = append(s, 4); fmt.Println(s)append 返回新切片,不会修改原切片。必须用返回值覆盖原变量,否则追加无效。
8.接口断言时忽略第二个返回值导致 panic
var i interface{} = "hello"; n := i.(int)var i interface{} = "hello"; n, ok := i.(int); if !ok { /* 处理失败 */ }单返回值类型断言在类型不匹配时会 panic。使用逗号 ok 模式可安全处理断言失败。
Go 关键字与内置函数映射关系:K = {k₁, k₂, ..., k₂₅}, F = {f₁, f₂, ..., fₙ}, M: K → F ∪ {∅}
K25 个 Go 关键字集合FGo 内置函数集合M关键字到内置函数的部分映射∅空映射,表示无对应内置函数以关键字 defer 为例:defer ∈ K,对应内置函数 recover() ∈ F,映射 M(defer) = recover()。实际使用中,defer 语句内调用 recover() 可捕获 panic 异常。
本工具收录了 Go 语言全部 25 个关键字(如 break、chan、default 等)和所有内置函数(如 append、copy、delete、len、cap、make、new、close、panic、recover 等),按官方 Go 规范整理。如果发现某个关键字或函数没列出来,通常是 Go 版本新增或极冷门的保留字(如 go1.18 的 any、comparable 属于类型约束,不在此列)。列表会随 Go 版本更新,目前覆盖到 Go 1.21。
本工具定位是快速速查——每个关键字和内置函数只给一句话定义和典型用法示例。如果觉得解释不够,可以点击结果区里的「官方文档」链接(如果有)或直接去 go.dev/ref/spec 看完整规范。另外,关键字和函数旁边的「示例」代码块是可直接运行的,把代码复制到本地 go run 里试一下,会比看长文更直观。
关键字(keyword)是 Go 语法层面的保留词,比如 if、for、switch,它们控制代码结构,不能用作变量名。内置函数(builtin)是 Go 预定义的函数,比如 len()、cap()、append(),可以直接调用无需 import。简单区分:关键字是“语法关键字”,内置函数是“预定义函数”。本工具在列表里用不同图标或颜色区分了这两类,点进去也能看到所属分类。
部分关键字(如 goto、fallthrough)在实际开发中使用频率极低,且用法非常单一,写示例反而容易误导。本工具优先为每个关键字和函数提供至少一个示例,但对于 goto、fallthrough、break(标签用法)这类特殊场景,示例会标注“极少使用”或“不推荐”,并给出官方说明链接。如果某个条目完全没示例,可能是技术限制,建议直接看官方 spec 对应章节。
本工具是纯前端实现,所有数据一次性加载到浏览器端,无需翻页。如果列表显示不全,可能是手机屏幕太小导致部分条目被折叠。可以尝试以下操作:1)横屏旋转手机,列表宽度会变大;2)在搜索框里输入关键字或函数名(支持模糊匹配),结果会实时过滤;3)如果仍然看不到全部,说明浏览器版本过低,建议升级或换 Chrome/Safari 最新版。
所有解释基于 Go 官方语言规范(go.dev/ref/spec)和标准库文档(pkg.go.dev/builtin),非第三方二手资料。本工具只做中文翻译和格式整理,不添加个人理解。如果发现某个解释与官方文档矛盾,请截图反馈,确认后会立即修正。另外,内置函数的参数类型和返回值说明也严格对照官方签名,不会凭空增减。
可以。本工具是纯前端页面(FE 实现),首次加载后所有数据缓存在浏览器内存中。只要页面打开过,断网后仍能正常搜索、展开查看。但如果关闭浏览器标签页或清除缓存,需要重新联网加载。建议常用的话,把页面添加到手机桌面或浏览器书签,离线场景下直接打开即可。
complex、real、imag 是 Go 内置的复数运算函数,在普通 Web 开发、后端 API 中几乎用不到,但在科学计算、信号处理、图形学等场景下是必备工具。本工具收录它们是为了完整性,不是推荐日常使用。如果你只做业务开发,忽略即可;如果恰好做数值计算,这些函数比用第三方库更高效。
map 在 Go 中既是关键字(用于声明 map 类型),又是内置函数(用于创建 map 的 make 函数的一个参数)。本工具会同时列出两个条目:一个在关键字列表(说明 map 类型语法),一个在内置函数列表(说明 make(map[K]V) 用法)。搜索“map”时结果会混排,但每个条目会标注“关键字”或“内置函数”标签,点进去也能看到明确分类。
隐私保证所有计算与处理均在你的浏览器本地完成,输入数据不会上传服务器,也不会保存或共享。