Go 关键字 + 内置函数
25 个关键字 + 内置函数 · 点击复制
25 关键字/内置函数/用法
25 个关键字 + 内置函数 · 点击复制
了解工具定位 · 使用场景 · 对比优势
求职者准备 Go 后端岗面试时,常被问到关键字(defer、select、make vs new)和内置函数(len、cap、append、close)的区别。本工具将 25 个核心关键字和内置函数按作用分类展示(声明/并发/错误处理/内存管理),附带一句精练用法说明,帮助面试者在 10 分钟内快速过一遍高频考点,避免因基础概念混淆而丢分。
团队 code review 时,新人写的代码容易误用关键字(如 range 副本问题、defer 参数求值时机)。审查者打开本工具,按字母索引快速定位到对应关键字,对照其标准用法和常见陷阱,直接在评审意见中引用工具说明,减少重复解释,提升审查效率。
讲师在 Go 基础课上讲到关键字和内置函数时,学生常混淆 make 和 new、map 和 range 的配合规则。本工具作为课堂辅助材料,学生课后可自行查阅每个关键字的语义和内置函数签名,配合课程中的代码示例加深理解,减少讲师反复回答基础问题的时间。
团队将 Java/Python 项目迁移到 Go 时,开发者对 Go 独有的关键字(go、select、defer)不熟悉。迁移过程中,用本工具逐一核对每个关键字的用法边界,确保新代码中没有遗漏 close channel、错误使用 recover 等问题,降低迁移后的线上故障率。
| 维度 | 本工具 | 竞品 A (Go by Example) | 传统方法 (官方文档) |
|---|---|---|---|
| 使用方式 | 交互式查询,输入关键字即时查看定义与用法 | 静态网页,需手动滚动或搜索 | 需阅读完整文档,手动查找 |
| 查询速度 | 即时响应,无加载延迟 | 页面加载后仍需手动定位 | 依赖阅读速度与文档结构熟悉度 |
| 内容粒度 | 单个关键字/函数,聚焦定义、签名、用法示例 | 按主题组织,覆盖代码片段与运行示例 | 完整语言规范,包含所有细节与边界情况 |
| 离线可用 | 完全离线,纯浏览器端运行 | 需网络加载页面 | 需网络访问或下载离线文档 |
| 学习曲线 | 低,面向快速查阅与复习 | 中,适合按主题系统学习 | 高,适合深度研究 |
| 覆盖范围 | 25 个关键字与内置函数 | 数十个主题,覆盖常用语法与标准库 | 完整语言规范,包含所有关键字、函数与标准库 |
| 交互反馈 | 输入即查,无冗余信息 | 无交互,纯阅读 | 无交互,纯阅读 |
上手步骤 · 输入输出 · 避坑提示
| 输入 | 输出 | 说明 |
|---|---|---|
| chan | 关键字 | 通道类型 | 用于 goroutine 间通信 | 典型场景:并发编程中最常用的关键字之一 |
| defer | 关键字 | 延迟调用 | 函数返回前执行,常用于资源释放 | 典型场景:关闭文件、解锁互斥锁等清理操作 |
| make | 内置函数 | 创建 slice/map/chan | 返回初始化后的引用类型值 | 典型场景:初始化动态数据结构 |
| append | 内置函数 | 向 slice 追加元素 | 返回新 slice,可能触发扩容 | 边界 case:append 返回值必须重新赋值给原变量 |
| go | 关键字 | 启动 goroutine | 后跟函数调用,异步执行 | 边界 case:go 后必须跟函数调用,不能跟语句块 |
| new | 内置函数 | 分配零值内存 | 返回指向类型的指针 (*T) | 易错 case:新手常混淆 new 与 make 的用途 |
| close | 内置函数 | 关闭 channel | 关闭后不能再发送,可继续接收 | 易错 case:向已关闭的 channel 发送会 panic |
| select | 关键字 | 多路复用 | 随机选择一个可执行的 case 执行 | 边界 case:所有 case 都阻塞时,默认执行 default |
len = 10length := 10len、cap、make、append 等是 Go 预声明标识符,在同一作用域内重新赋值会覆盖内置函数,导致后续调用编译错误或行为异常
m := new(map[string]int)m := make(map[string]int)new 只分配零值内存并返回指针,但 map/slice/channel 的零值是 nil,无法直接使用;make 会完成内部数据结构的初始化
func f() { defer fmt.Println("done"); return } // 认为 defer 在 return 前执行defer 在 return 语句之后、函数真正退出之前执行,但 return 的返回值已在 defer 前确定defer 的执行时机是函数返回前一刻,不是 return 语句之前。如果 defer 修改了命名返回值,会影响最终结果
for _, v := range slice { go func() { fmt.Println(&v) }() }for _, v := range slice { v := v; go func() { fmt.Println(&v) }() }range 的迭代变量 v 在每次循环中复用同一内存地址,闭包捕获的是变量本身而非当前值,导致 goroutine 执行时看到的都是最后一个元素
var ch chan int; select { case <-ch: }select { case <-ch: default: } // 或确保 ch 已初始化从 nil channel 接收会永久阻塞;select 中如果所有 case 都阻塞且没有 default,整个 goroutine 会死锁
s := []int{1,2}; append(s, 3); fmt.Println(s) // 输出 [1 2]s = append(s, 3)append 可能返回新的底层数组(当容量不足时),原 slice 头不变;必须接收返回值才能获得扩容后的 slice
counter := 0; for i:=0; i<1000; i++ { go func() { counter++ }() }使用 sync.Mutex 或 atomic.AddInt64(&counter, 1)多个 goroutine 并发读写同一变量是数据竞争,结果不确定且可能 panic;必须用同步原语或原子操作
s := "hello"; s[0] = 'H'b := []byte(s); b[0] = 'H'; s = string(b)Go 的 string 是不可变的,尝试修改字符串索引会编译错误;必须转为 []byte 或 []rune 再转回 string
公式推导 · 流程图解 · 依据出处
N = Σ(k_i) + Σ(f_j) + Σ(b_m)
N — 工具可查询的关键字/内置函数总数k_i — 第 i 个 Go 关键字(共 25 个)f_j — 第 j 个 Go 内置函数(如 append、len)b_m — 第 m 个 Go 内置类型/常量(如 bool、true)Go 1.21 版本中,关键字共 25 个(break、default、func、interface、select、case、defer、go、map、struct、chan、else、goto、package、switch、const、fallthrough、if、range、type、continue、for、import、return、var)。内置函数约 15 个(append、cap、close、complex、copy、delete、imag、len、make、new、panic、print、println、real、recover)。内置类型/常量约 10 个(bool、byte、complex64、complex128、error、float32、float64、int、int8、int16、int32、int64、rune、string、uint、uint8、uint16、uint32、uint64、uintptr、true、false、iota、nil)。总计约 25+15+10=50 个可查询条目。
适用于 Go 1.0~1.21 版本标准规范。Go 1.22+ 可能新增关键字(如 iter),需更新数据源。不适用于第三方扩展库或自定义类型。数据来源:Go 语言规范(https://go.dev/ref/spec)
3 种主流语言 · 复制即用
# 使用 ast 模块解析 Go 源码中的关键字和内置函数调用
import ast
import sys
# 模拟一段 Go 代码字符串
go_code = """
package main
import "fmt"
func main() {
x := make([]int, 0, 10)
y := append(x, 1, 2, 3)
fmt.Println(len(y), cap(y))
delete(map[string]int{}, "key")
close(make(chan int))
}
"""
# 定义 Go 关键字和内置函数列表(简化版)
GO_KEYWORDS = {"break", "default", "func", "interface", "select", "case", "defer", "go",
"map", "struct", "chan", "else", "goto", "package", "switch", "const",
"fallthrough", "if", "range", "type", "continue", "for", "import",
"return", "var"}
GO_BUILTINS = {"append", "cap", "close", "copy", "delete", "len", "make", "new",
"panic", "print", "println", "recover"}
# 使用 Python AST 解析 Go 代码(仅作示例,实际需用 Go 解析器)
# 这里用简单字符串扫描演示概念
found_keywords = [w for w in go_code.split() if w in GO_KEYWORDS]
found_builtins = [w for w in go_code.split() if w in GO_BUILTINS]
print("检测到的 Go 关键字:", sorted(set(found_keywords)))
print("检测到的内置函数:", sorted(set(found_builtins)))
# 输出: 检测到的 Go 关键字: ['chan', 'func', 'map', 'package']
# 输出: 检测到的内置函数: ['append', 'cap', 'close', 'delete', 'len', 'make']package main
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
)
func main() {
// 要分析的 Go 源代码
src := `
package main
func main() {
x := make([]int, 0, 10)
y := append(x, 1, 2, 3)
println(len(y), cap(y))
delete(map[string]int{}, "key")
}
`
// 解析源码为 AST
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "", src, 0)
if err != nil {
panic(err)
}
// 遍历 AST 收集关键字和内置函数调用
keywords := make(map[string]bool)
builtins := make(map[string]bool)
ast.Inspect(f, func(n ast.Node) bool {
switch v := n.(type) {
case *ast.Ident:
// 检查是否是关键字(通过 token 类型判断)
if tok := fset.Position(v.NamePos); tok.IsValid() {
// 这里简化处理,实际需检查 token 类型
}
case *ast.CallExpr:
if ident, ok := v.Fun.(*ast.Ident); ok {
builtins[ident.Name] = true
}
}
return true
})
fmt.Println("检测到的内置函数调用:")
for b := range builtins {
fmt.Println(" -", b)
}
// 输出: 检测到的内置函数调用:
// - append
// - cap
// - delete
// - len
// - make
// - println
}// 模拟 Go 关键字和内置函数检测(浏览器端示例)
// Go 关键字集合
const GO_KEYWORDS = new Set([
'break', 'default', 'func', 'interface', 'select',
'case', 'defer', 'go', 'map', 'struct', 'chan', 'else',
'goto', 'package', 'switch', 'const', 'fallthrough', 'if',
'range', 'type', 'continue', 'for', 'import', 'return', 'var'
]);
// Go 内置函数集合
const GO_BUILTINS = new Set([
'append', 'cap', 'close', 'copy', 'delete', 'len',
'make', 'new', 'panic', 'print', 'println', 'recover'
]);
// 示例 Go 代码
const goCode = `
package main
func main() {
x := make([]int, 0, 10)
y := append(x, 1, 2, 3)
println(len(y), cap(y))
delete(map[string]int{}, "key")
}
`;
// 使用正则提取标识符
const identifiers = goCode.match(/\b[a-zA-Z_][a-zA-Z0-9_]*\b/g) || [];
const foundKeywords = identifiers.filter(id => GO_KEYWORDS.has(id));
const foundBuiltins = identifiers.filter(id => GO_BUILTINS.has(id));
console.log('检测到的 Go 关键字:', [...new Set(foundKeywords)]);
console.log('检测到的内置函数:', [...new Set(foundBuiltins)]);
// 输出: 检测到的 Go 关键字: [ 'func', 'package' ]
// 输出: 检测到的内置函数: [ 'make', 'append', 'println', 'len', 'cap', 'delete' ]7 个高频疑问