Go HTML模板中的字段检测

Is it possible to check if a struct field exists from within a Go HTML template?

For example, given the following template:

{{if .FieldA}}
    <a>{{.FieldA}}</a>
{{end}

and structs defined as:

type MyStruct struct{  
    var FieldA string
    var FieldB string
}
// In this struct FieldA is unavailable
type MyStruct2 struct{  
    var FieldB string
}

Passing MyStruct into the template will work fine. However, passing MyStruct2 into the template will result in error. While the if statement can check for nil values, it throws an error (killing the template executor) when it encounters a field which doesn't exist in the current struct.

Sometimes a particular field is only going to be available in certain structs, so is there a way to check if the field exists prior to attempting to access it?

I've had no luck with the official documentation and have come to the conclusion that perhaps there is no elegant solution.

There's not a built-in way to check for the presence of a field, but it is possible to write a template function to do the check:

func hasField(v interface{}, name string) bool {
  rv := reflect.ValueOf(v)
  if rv.Kind() == reflect.Ptr {
    rv = rv.Elem()
  }
  if rv.Kind() != reflect.Struct {
    return false
  }
  return rv.FieldByName(name).IsValid()
}

Use the function in a template like this:

{{if hasField . "FieldA"}}<a>{{.FieldA}}</a>{{end}}

Create the template with hasField in the func map:

 t := template.New("").Funcs(template.FuncMap{"hasField": hasField}).Parse(d)

playground example