模板:访问切片中结构体的嵌套字段

huangapple go评论75阅读模式
英文:

Templates: accessing nested fields of slice of structs

问题

我想使用Go模板输出slice[0].type。虽然打印工作正常:

{{ index .Slice 0 | printf "%+v" }} // {Type:api.Meter ShortType:Meter VarName:meter}

但是打印字段不起作用:

{{ index .Slice 0 | .Type }} // template: gen:43:26: 执行"gen"时在<.Type>处: 无法在类型struct { API string; Package string; Function string; BaseTypes []main.baseType; Types map[string]main.typeStruct; Combinations [][]string }中评估字段Type

错误消息表明评估的是外部循环的字段,而不是index调用的结果。

访问嵌套切片字段的正确语法是什么?

英文:

I would like to output slice[0].type using go templates. While printing works:

{{ index .Slice 0 | printf &quot;%+v&quot; }} // {Type:api.Meter ShortType:Meter VarName:meter}

printing the field doesn't:

{{ index .Slice 0 | .Type }} // template: gen:43:26: executing &quot;gen&quot; at &lt;.Type&gt;: can&#39;t evaluate field Type in type struct { API string; Package string; Function string; BaseTypes []main.baseType; Types map[string]main.typeStruct; Combinations [][]string }

The error message indicates that the outer loops fields are evaluated, not the result of the index call.

What is the correct syntax to access nested fields of slices?

答案1

得分: 3

printf是一个内置的模板函数。当你将index .Slice 0链接到printf中时,该值将作为最后一个参数传递给printf。访问Type字段不是一个函数调用,你不能在其后面链接。链式调用中的.Type将在当前的"dot"上进行求值,链式调用不会改变"dot"。

使用括号将切片表达式分组,然后应用字段选择器:

{{ (index .Slice 0).Type }}

测试示例:

type Foo struct {
	Type string
}

t := template.Must(template.New("").Parse(`{{ (index .Slice 0).Type }}`))

params := map[string]interface{}{
	"Slice": []Foo{{Type: "Bar"}},
}

if err := t.Execute(os.Stdout, params); err != nil {
	panic(err)
}

输出结果为(在Go Playground上尝试):

Bar
英文:

printf is a builtin template function. When you chain index .Slice 0 into printf, the value is passed as the last argument to printf. Accessing the Type field is not a function call, you can't chain into that. .Type in the chain will be evaluated on the current "dot", chaining does not change the dot.

Group the slicing expression using parenthesis, then apply the field selector:

{{ (index .Slice 0).Type }}

Example testing it:

type Foo struct {
	Type string
}

t := template.Must(template.New(&quot;&quot;).Parse(`{{ (index .Slice 0).Type }}`))

params := map[string]interface{}{
	&quot;Slice&quot;: []Foo{{Type: &quot;Bar&quot;}},
}

if err := t.Execute(os.Stdout, params); err != nil {
	panic(err)
}

Which outputs (try it on the Go Playground):

Bar

huangapple
  • 本文由 发表于 2021年9月26日 16:08:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/69332956.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定