LeetCode只按函数签名调用,不运行main;本地测试需手动补main并构造输入切片;函数名、参数及返回值类型必须严格匹配;禁止未初始化map、越界访问和非法import。

别在本地写 main 函数调用题目函数再提交——LeetCode 后端根本不运行你的 main,只按签名调用你定义的函数;一提交就编译失败,八成是这个原因。
LeetCode Go 题目到底怎么本地测试
题目给的只是函数声明(比如 func twoSum(nums []int, target int) []int),没有 main,但你要验证逻辑就得跑起来。
- 新建一个
main.go,把题目函数完整复制进去 - 手动补一个
func main(),在里面构造输入并打印返回值,例如:func main() { fmt.Println(twoSum([]int{2, 7, 11, 15}, 9)) } - 别用
fmt.Scan或bufio.Scanner读输入——LeetCode 不喂 stdin,它只校验函数返回值;本地调试才需要自己造数据 - 切片字面量必须写成
[]int{2,7,11,15},不是[]{}int或[]{2,7,11,15},后者会报invalid array length
为什么本地输出对,提交却 panic 或编译失败
LeetCode 后端用反射严格匹配函数签名,任何偏差都会导致运行时崩溃或编译不通过。
- 函数名大小写必须完全一致:
twoSum写成TwoSum、two_sum、twosum全部失败 - 参数类型不能“看着像”:输入是
[]int,就不能改成int[](Go 根本不支持这种语法) - 返回值类型必须精确匹配:题目要求
[]int,返回[2]int、nil(类型不兼容)、或漏写return都会编译失败 - 额外
import要谨慎:只导入标准库已预置的包(如fmt、math、sort);加了github.com/xxx或未使用的包,直接编译失败
常见 panic 场景和绕过写法
Go 不做隐式边界检查,很多 panic 在本地小数据测不出,一交大用例就崩。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
-
index out of range:空切片访问nums[0]前必须先判len(nums) == 0;快慢指针中fast.Next.Next前得同时检查fast != nil && fast.Next != nil -
assignment to entry in nil map:声明var m map[int]int后直接m[k] = v必 panic;必须初始化为m := make(map[int]int)或带容量的make(map[int]int, 1e5) - 字符串遍历用
for i := range s而非for i := 0; i ——后者按 byte 索引,在中文或 emoji 下会越界或跳字;LeetCode 输入多为 ASCII,前者更稳也更符合习惯 - 切片扩容后原变量不变:
append(nums, x)返回新切片,不修改原nums;需要生效就得显式赋值:nums = append(nums, x)
输入处理别踩 bufio.Scanner 默认坑
LeetCode 后端输入是单次完整流(一行数组 / 多行树序列),但本地容易误用 scanner.Scan() 循环读 EOF,导致超时或 panic。
- 单行数组输入(如
[1,2,3]):优先用json.Unmarshal+strings.TrimSpace,比fmt.Scanf更鲁棒 - 多行输入(如树的 BFS 序列):用
bufio.NewReader(os.Stdin),但必须限制读取行数;别无脑ReadString('\n'),否则空行或末尾换行会卡住 - 空输入或空行:
strings.Split("", ",")返回[]string{""},不是空切片;要手动过滤掉空字符串 - 链表 / 树节点构造别手写嵌套字面量——易错三层括号;写辅助函数如
Ints2List或层序建树,字段名严格用Val/Left/Right(大小写敏感)
真正卡人的从来不是语法,而是 LeetCode 的 Go 运行环境只认函数签名、不跑 main、不帮你兜底 nil map 和越界访问——这些地方一松懈,本地绿了,提交红得莫名其妙。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










