golangのテンプレート内でメソッドを呼び出す
at 2016-06-03 02:02 (UTC)
text/template
のサンプルをいくつか見てみたところ、構造体を渡してフィールドを埋め込んで表示するサンプルばかりだった。じゃあメソッド呼べるの?と思ったので試してみた。
package main
import (
"os"
"text/template"
)
type Person struct {
Name string
City string
}
func (p Person) GetAge() int {
return 36
}
func main() {
tmpl, err := template.New("test").Parse("{{.Name}}({{.GetAge()}}) lives in {{.City}}.")
if err != nil {
panic(err)
}
p := Person{"pinzolo", "Kyoto"}
err = tmpl.Execute(os.Stdout, p)
if err != nil {
panic(err)
}
}
panic: template: test:1: unexpected "(" in operand<br /><br />goroutine 1 [running]:
panic(0x13f660, 0xc82000a440)
/usr/local/Cellar/go/1.6.2/libexec/src/runtime/panic.go:481 +0x3e6
main.main()
/Users/pinzolo/.cache/junkfile/2016/06/2016-06-03-101728.go:20 +0x24b
exit status 2
できなかった。
括弧が unexpected なら、括弧なしならどうなの??
package main
import (
"os"
"text/template"
)
type Person struct {
Name string
City string
}
func (p Person) GetAge() int {
return 36
}
func main() {
tmpl, err := template.New("test").Parse("{{.Name}}({{.GetAge}}) lives in {{.City}}.")
if err != nil {
panic(err)
}
p := Person{"pinzolo", "Kyoto"}
err = tmpl.Execute(os.Stdout, p)
if err != nil {
panic(err)
}
}
pinzolo(36) lives in Kyoto.
出来た。正直言って予想外だった。
じゃあ、引数はどうやって渡すの?
package main
import (
"os"
"text/template"
)
type Person struct {
Name string
City string
}
func (p Person) GetAge() int {
return 36
}
func (p Person) GetFutureAge(yearAfter int) int {
return p.GetAge() + yearAfter
}
func main() {
tmpl, err := template.New("test").Parse("{{.Name}}({{.GetAge}}) lives in {{.City}}. 2 years later he is {{.GetFutureAge 2}}.")
if err != nil {
panic(err)
}
p := Person{"pinzolo", "Kyoto"}
err = tmpl.Execute(os.Stdout, p)
if err != nil {
panic(err)
}
}
len
とかのビルトイン関使うようにスペース開ければいいかな?
package main
import (
"os"
"text/template"
)
type Person struct {
Name string
City string
}
func (p Person) GetAge() int {
return 36
}
func (p Person) GetFutureAge(yearAfter int) int {
return p.GetAge() + yearAfter
}
func main() {
tmpl, err := template.New("test").Parse("{{.Name}}({{.GetAge}}) lives in {{.City}}. 2 years later he is {{.GetFutureAge 2}}.")
if err != nil {
panic(err)
}
p := Person{"pinzolo", "Kyoto"}
err = tmpl.Execute(os.Stdout, p)
if err != nil {
panic(err)
}
}
pinzolo(36) lives in Kyoto. 2 years later he is 38.
出来た。
じゃあ2つ以上の引数はスペース区切りかな?
package main
import (
"os"
"text/template"
)
type Person struct {
Name string
City string
}
func (p Person) GetAge() int {
return 36
}
func (p Person) GetFutureAge(yearAfter int, other int) int {
return p.GetAge() + yearAfter + other
}
func main() {
tmpl, err := template.New("test").Parse("{{.Name}}({{.GetAge}}) lives in {{.City}}. 5 years later he is {{.GetFutureAge 2 3}}.")
if err != nil {
panic(err)
}
p := Person{"pinzolo", "Kyoto"}
err = tmpl.Execute(os.Stdout, p)
if err != nil {
panic(err)
}
}
pinzolo(36) lives in Kyoto. 5 years later he is 41.
やっぱり。
趣向を変えて、構造体のポインタを渡してもうまく動くかな?
package main
import (
"os"
"text/template"
)
type Person struct {
Name string
City string
}
func (p *Person) GetAge() int {
return 36
}
func (p *Person) GetFutureAge(yearAfter int) int {
return p.GetAge() + yearAfter
}
func main() {
tmpl, err := template.New("test").Parse("{{.Name}}({{.GetAge}}) lives in {{.City}}. 2 years later he is {{.GetFutureAge 2}}.")
if err != nil {
panic(err)
}
p := &Person{"pinzolo", "Kyoto"}
err = tmpl.Execute(os.Stdout, p)
if err != nil {
panic(err)
}
}
package main
import (
"os"
"text/template"
)
type Person struct {
Name string
City string
}
func (p Person) GetAge() int {
return 36
}
func (p Person) GetFutureAge(yearAfter int) int {
return p.GetAge() + yearAfter
}
func main() {
tmpl, err := template.New("test").Parse("{{.Name}}({{.GetAge}}) lives in {{.City}}. 2 years later he is {{.GetFutureAge 2}}.")
if err != nil {
panic(err)
}
p := &Person{"pinzolo", "Kyoto"}
err = tmpl.Execute(os.Stdout, p)
if err != nil {
panic(err)
}
}
pinzolo(36) lives in Kyoto. 2 years later he is 38.
問題ない。構造体に定義したメソッドもポインタに定義したメソッドも呼び出せてる。
結構色々出来るんだな text/template