私はこの構造を持っています:
const (
paragraph_hypothesis = 1<<iota
paragraph_attachment = 1<<iota
paragraph_menu = 1<<iota
)
type Paragraph struct {
Type int // paragraph_hypothesis or paragraph_attachment or paragraph_menu
}
Type
に依存した方法で段落を表示したい。
私が見つけた唯一の解決策は、GoでisAttachment
とネストされた{{if}}
をテストするType
のような専用関数に基づいていました。
{{range .Paragraphs}}
{{if .IsAttachment}}
-- attachement presentation code --
{{else}}{{if .IsMenu}}
-- menu --
{{else}}
-- default code --
{{end}}{{end}}
{{end}}
実際、私はさらに多くの型を持っているので、さらに奇妙になり、IsSomething
関数を使用したGoコードと{{end}}
を使用したテンプレートの両方が乱雑になります。
クリーンなソリューションは何ですか? goテンプレートにいくつかのswitch
またはif/elseif/else
ソリューションがありますか?または、これらのケースを処理するためのまったく異なる方法ですか?
テンプレートにはロジックがありません。彼らはこの種の論理を持つべきではありません。最大のロジックは、if
の束です。
このような場合、次のようにする必要があります。
{{if .IsAttachment}}
-- attachment presentation code --
{{end}}
{{if .IsMenu}}
-- menu --
{{end}}
{{if .IsDefault}}
-- default code --
{{end}}
はい、{{else if .IsMenu}}
を使用できます
template.FuncMap にカスタム関数を追加することにより、switch
機能を実現できます。
以下の例では、printPara (paratype int) string
という関数を定義しました。これは、定義済みの段落タイプの1つを受け取り、それに応じて出力を変更します。
実際のテンプレートでは、.Paratype
はprintpara
関数にパイプされます。これは、テンプレートでパラメーターを渡す方法です。 FuncMap
sに追加される関数の出力パラメーターの数と形式には制限があることに注意してください。 このページ には、最初のリンクだけでなく、いくつかの良い情報があります。
package main
import (
"fmt"
"os"
"html/template"
)
func main() {
const (
paragraph_hypothesis = 1 << iota
paragraph_attachment = 1 << iota
paragraph_menu = 1 << iota
)
const text = "{{.Paratype | printpara}}\n" // A simple test template
type Paragraph struct {
Paratype int
}
var paralist = []*Paragraph{
&Paragraph{paragraph_hypothesis},
&Paragraph{paragraph_attachment},
&Paragraph{paragraph_menu},
}
t := template.New("testparagraphs")
printPara := func(paratype int) string {
text := ""
switch paratype {
case paragraph_hypothesis:
text = "This is a hypothesis\n"
case paragraph_attachment:
text = "This is an attachment\n"
case paragraph_menu:
text = "Menu\n1:\n2:\n3:\n\nPick any option:\n"
}
return text
}
template.Must(t.Funcs(template.FuncMap{"printpara": printPara}).Parse(text))
for _, p := range paralist {
err := t.Execute(os.Stdout, p)
if err != nil {
fmt.Println("executing template:", err)
}
}
}
生産物:
これは仮説です
これは添付ファイルです
メニュー
1:
2:
3:任意のオプションを選択:
これがお役に立てば幸いです。コードを少しクリーンアップできると確信していますが、提供されたサンプルコードに近づけるように努めました。