I don't see any type of startswith
function in the Go text/template
package. Is this the best implementation?
{{if eq (slice $c 0 5) "begin"}}
There is no builtin startswith
template function.
The cleanest is if you register a custom function with that functionality:
func main() {
t := template.Must(template.New("").Funcs(template.FuncMap{
"hasPrefix": strings.HasPrefix,
}).Parse(src))
for _, s := range []string{"foo", "begining"} {
if err := t.Execute(os.Stdout, s); err != nil {
panic(err)
}
}
}
const src = `{{.}}: {{if hasPrefix . "begin"}}yes{{else}}no{{end}}
`
This will output (try it on the Go Playground):
foo: no
begining: yes
If you can't or don't want to register a custom function, slice
works for strings, but you must use it with care: if the input string is shorter than 5 bytes, you'll get a template execution error!
Instead (if you don't want to register a custom function), I suggest to use the builtin printf
function with precision being the length of the string to compare to. printf
will not panic if the input string is shorter:
{{if eq (printf "%.5s" .) "begin"}}yes{{else}}no{{end}}
This outputs the same. Try this one on the Go Playground.
Note that using hasPrefix
is safer, cleaner and simpler as we don't have to hard-code the length of the prefix (5
).
Note that using explicit argument indices we can also make this part dynamic:
{{$prefix := "begin"}}{{if eq (printf "%.[1]*s" (len $prefix) .) $prefix}}yes{{else}}no{{end}}
As you can see, we could get rid of the hard-coded length of 5
of the prefix. This again outputs the same, try it on the Go Playground.
One last thing to note: slicing a string interprets indices as byte-indices, while the precision used in a format string is interpreted as rune count!