GoLand 的完美 leetcode 刷题体验
大概从大二开始,我开始陆陆续续地刷一些 leetcode 题,最开始是用 java,之后很长一段时间在用 go。在刷题的过程中,我的刷题方式发生了很大的变化。
最开始是使用 leetcode 的在线编辑器刷题,题目极其简单还好,稍微复杂一些需要引库,在线编辑器的自动补全能把人逼疯…没多久,我就弃用了这种最原始的刷题方法。
一个小提示:参加技术招聘时的笔试有很大可能是在网页编辑器中作答的。
平常不使用在线编辑器刷题主要是为了方便,但也不要因此变成离开 IDE 后就不知所措、标准库方法名都忘记的工具型选手!
抛开在线编辑器,能想到的方法当然只有在本地编程了。最开始是 vscode + golang 拓展,每次都要:
- 新建代码文件,命名为题目名称;
- 打开 leetcode 题目描述,把代码模板粘贴下来;
- 实现算法,复制粘贴到 leetcode 在线编辑器中,提交测试;
- 如未通过则重复 3 。
重复性劳动总是让人烦躁,于是我找到了 vscode 中的 leetcode 拓展,该拓展可在 vscode 中展示题目列表,选中题目后自动在 vscode 中预览题目并生成文件描述和模板到指定文件夹。这在很大程度上节省了我的工作量。
然而,随着某次 go 或 vscode 的更新,vscode 内对 go 的自动补全检查扩大到了文件夹级别。(或许是随着 gomod 的引入?我已经不太清楚了)因为不同题目全部在文件夹的同一级,所有的在不同题目中定义的结构体、函数只要重名就会报重声明错误,而这在一个存储上百道题解的文件夹中带来的是毁天灭地的灾难。我的源码文件近乎一半被标红,每每看到那一片片的红色波浪线都给我带来生理上的不适。
现在想来应该多去查查 leetcode 拓展的文档的,或许有什么解法也说不定?
时间过得飞快,转眼间就毕业工作了。虽然工作主要使用的语言是 python,但我平时还是习惯写写 go。前段时间几位同事说要比赛力扣连续打卡一个月,我也顺便参与了。这次从 vscode 换成了 goland,我打算一步到位配置一个完美的力扣刷题环境。
以下是我的配置过程及思路:(唠叨半天总算说到重点了。)
安装 leetcode 刷题插件
与 vscode 类似,GoLand 中也有类似的刷题插件,名为 LeetCode Editor。
组织源码文件夹
安装拓展完成后,可在设置中调整 leetcode 题目描述、源码模板下载到的位置。假设你把位置填成了 /home/amtoaer/Documents/code/
。
随便点击一个题目,将会发现实际的目录结构如下:
1 | # 此时位于 /home/amtoaer/Documents/code/ |
也就是说,如果使用中文刷题,并把拓展配置中的TempFilePath
设置为$DIR
的话,实际的源码所在目录为$DIR/leetcode/editor/cn/
,并且该目录下还会有一个多余的doc
文件夹用于存储题目描述。
如果有保存源码文件的需求,请到该目录下寻找。
如果你像我一样喜欢把题目上传到 git 仓库,在/leetcode/editor/cn/
中新建 git 仓库并在该文件夹下新建.gitignore
,于其中写入一行:
1 | doc |
将题目描述文档所在的文件夹忽略即可。
解决同文件夹下的命名冲突错误
通过查阅相关资料,我得知在 go 源码文件中做以下任意两个操作,可使 go build 忽略该文件信息:
- 在源码文件名前加入下划线
_
; - 在源码文件内写入
//go:build ignore
。
然而,这两种方式都有致命缺陷,即在 GoLand 的编辑器头部有无法关闭的醒目标识,这对于完美主义的我们是不能接受的。
继续查找资料,发现 leetcode editor 拓展是支持自定义代码文件模板和路径的。且 #304 提到可通过在自定义文件名中加入路径分割符来新建文件夹。
既然平铺的源码文件会导致重声明错误,那我们可以给每个源码文件都创建一个新的文件夹。
首先勾选Custom Template
选项,接着将Code FileName
修改为:
1 | $!{question.frontendQuestionId}.${question.title}/solution_test |
这将使文件结构变为:
1 | ├── 102.二叉树的层序遍历 |
这时我们已经做到了单个代码文件的命名隔离。
易于调试
得益于拓展的自定义代码模板功能与区域代码提交机制,我们可以非常简单地调试我们的代码。
区域代码提交:指拓展维护两条固定注释,分别作为提交位置的起点和终点,提交时只有这两个注释之间的代码会被提交。
我们可以把调试部分(如单测或者 main 函数)放在提交区域外,这样不会对提交的代码有任何影响。
一个简易的模板如下图,需将其填写在 leetcode plugin 配置中的Code Template
项:
1 | package leetcode |
这样只需要把样例输入输出写在测试函数内,点击运行即可。
一个依此模板生成的文件如下:
1 | package leetcode |
在文件中实现算法、并在本地调试的例子如图所示:
至此该方案已经比较完美了。
旧代码仓库的迁移
原有的代码虽然不会继续调试了,但仍然有保留价值。我选择把它们整理成相同的目录结构。
按上述流程设置 leetcode editor 插件。
克隆原有的平铺型代码仓库,将所有的代码以及
.git
文件夹整个移动到$DIR/leetcode/editor/cn/
。写一个简单的
python
脚本用于迁移源码:1
2
3
4
5
6
7
8
9
10
11
12
13import os
files = os.listdir('.')
for file in files:
items = file.rsplit('.', 1)
if len(items) != 2:
continue
name, extension = items
if extension != 'go':
continue
os.mkdir(name)
os.rename(file, f'{name}/solution_test.go')git add
&git commit
&git push