live template需结合$var$占位符与表达式函数(如classname()、fieldnames()、groovyscript)实现上下文感知,必须勾选“enable live template with expression”并正确设置applicable in范围(如go: statement),否则无法动态推导类型、字段名等信息。

Live Template 怎么写才能带上下文变量
GoLand 的 Live Template 默认是静态占位符,但真正好用的模板必须能自动读取当前光标所在位置的类型、字段名、包名等信息。关键不是“写死变量”,而是用 $VAR$ + 表达式函数组合实现动态推导。
比如你想在 type User struct { Name string } 里输入 tojson + Tab,自动生成 func (u *User) ToJSON() ([]byte, error) { ... } —— 这个 User 和 Name 就不能手动填,得让 IDE 自己抓。
- 右键结构体名 →
Refactor→Extract Interface后,IDE 已经知道当前类型名,Live Template 可调用className()函数获取 - 光标停在 struct 字段上时,
fieldNames()能返回所有字段名数组,配合groovyScript可筛选出当前字段 -
editor.getSelectedText()在选中一段代码后生效,适合“包围模板”场景(如给一段逻辑加defer或recover)
为什么 forr 模板能自动补 range 变量名,而你写的模板不行
因为内置模板用了 groovyScript 表达式,而新手常只用纯文本占位符。例如官方 forr 模板实际内容是:
for $INDEX$ := range $ITERABLE$ {
$END$
}
其中 $ITERABLE$ 并非固定值,它背后绑定了一个表达式:groovyScript("def arr = _1; if (arr == null) return ''; def type = arr.getType(); if (type != null && type.getArrayComponentType() != null) return type.getArrayComponentType().getName(); return '[]'")
GoLand 2026.1.1 是 2026.1 发布后的首个维护修正版本,适合已经开始体验 2026.1 新功能并希望同步补丁的开发者。它更适合用于入门项目、现有项目迁移测试和 IDE 行为验证。
这意味着:光标放在 users []User 变量上按 forr,$ITERABLE$ 就自动变成 users,$INDEX$ 也按数组元素类型推导为 user。
- 自定义模板必须勾选
Enable live template with expression才能用groovyScript - JetBrains 官方文档里没公开全部可用函数,但
className()、methodName()、variableName()是稳定可用的 - 错误写法:
$TYPE$直接写死,不绑定任何表达式 → Tab 后只能手动输string、int等
常见坑:模板生效范围设错导致根本不出现在补全列表
Live Template 不是全局生效的,它严格依赖 Applicable in 设置。比如你写了个生成 http.HandlerFunc 的模板,但适用范围只设了 Go: declaration,那在 router.HandleFunc("/path", handler) 这种调用处就完全不会触发。
- 最常用范围:
Go: statement(函数体内)、Go: declaration(包级声明)、Go: expression(任意表达式上下文) - 如果模板想在
func关键字后触发,必须包含Go: declaration;如果想在if块里用,就得加Go: statement - 误勾
Reformat according to style可能导致生成后格式错乱,尤其涉及多行缩进时,建议先关掉测试效果
调试模板:怎么知道它到底读到了什么
写完模板别急着用,先验证上下文是否被正确捕获。最简单方式是临时把表达式输出成注释:
// className: $className()$; fields: $fieldNames()$; selected: $editor.getSelectedText()$
然后在不同位置触发模板,看注释里打印出什么。这是唯一靠谱的调试路径。
-
$className()$在 struct 定义内返回空字符串,在方法 receiver 上才返回类型名 -
$fieldNames()$返回的是字符串数组 JSON 形式,如["ID","Name"],需用groovyScript解析 - 如果所有变量都为空,八成是适用范围(
Applicable in)或光标位置不对,不是表达式写错了
className() 会返回 interface{} 而非具体类型,这点必须提前验证。










