Home > Enterprise >  Templates: accessing nested fields of slice of structs
Templates: accessing nested fields of slice of structs

Time:09-26

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

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

printing the field doesn't:

{{ index .Slice 0 | .Type }} // template: gen:43:26: executing "gen" at <.Type>: can'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?

CodePudding user response:

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("").Parse(`{{ (index .Slice 0).Type }}`))

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

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

Which outputs (try it on the Go Playground):

Bar
  • Related