
在go模板中无法直接使用方括号语法(如.a[2])访问数组、切片或映射的元素,会报错“bad character U+005B”;必须通过内置函数index实现安全、合法的索引访问。
在go模板中无法直接使用方括号语法(如`.a[2]`)访问数组、切片或映射的元素,会报错“bad character u+005b”;必须通过内置函数`index`实现安全、合法的索引访问。
Go模板语言(text/template 和 html/template)为保障安全性与解析确定性,不支持原生的方括号索引表达式(例如 .items[0] 或 .users[“alice”])。因此,当你尝试写 {{ .a[2] }} 时,模板解析器会在词法分析阶段就报错:bad character U+005B ‘[‘ —— 因为 [ 不是合法的模板操作符。
✅ 正确做法是使用内置函数 index:
{{ index .a 2 }}
index 是一个灵活且类型安全的函数,支持对多种数据结构进行索引访问:
| 数据类型 | 示例调用 | 说明 |
|---|---|---|
| 切片/数组 | {{ index .users 0 }} | 按整数下标访问第1个元素 |
| 映射(map) | {{ index .config “timeout” }} | 按字符串键访问值 |
| 多层嵌套 | {{ index (index .data “items”) 1 }} 或 {{ index .data “items” 1 }} | index 支持链式参数,等价于 data.items[1] |
? 实用示例(完整Go代码 + 模板):
// Go 程序 type PageData struct { Names []string Props map[string]int } data := PageData{ Names: []string{"Alice", "Bob", "Charlie"}, Props: map[string]int{"age": 30, "score": 95}, } tmpl := template.Must(template.New("").Parse(` First name: {{index .Names 0}} Third name: {{index .Names 2}} Age: {{index .Props "age"}} `)) tmpl.Execute(os.Stdout, data) // 输出: // First name: Alice // Third name: Charlie // Age: 30
⚠️ 注意事项:
- index 函数在越界或键不存在时返回零值(如 nil、0、””),不会 panic,但需在业务逻辑中主动校验;
- 若需容错处理,可结合 if 判断:
{{ if ge (len .a) 3 }}{{ index .a 2 }}{{ else }}N/A{{ end }} - index 不支持负数索引(如 index .a -1 无效),也不支持切片语法(如 [:2]);
- 对结构体字段仍用点号访问(如 .User.Name),仅容器类型需 index。
总结:Go模板中访问数组/切片/映射元素的唯一标准方式是 index 函数。它既是语法要求,也是类型安全与模板健壮性的设计体现。养成 {{ index .x y }} 的习惯,可避免解析错误,并提升模板的可维护性与可读性。