Golang 字符串模板處理
Golang的template包用於解析字符串模板,語法採用Mustache 語法,使用非常簡單。
1. 目標
新增下面模板文件,後面需要解析該文件:
{{.Product}} of {{.Company}}
{{if .ProductList -}}
ProductList:
{{- range .ProductList}}
* {{. -}}
{{end}}
{{end}}
像{{.Product}} 和 {{.Company}}作爲模板變量在解析時會被替換。其他{{if}} 和 {{range}}是動作,也會被評估執行。在{{}}兩邊的橫槓-
用於去除變量兩邊的空格。.
表示迭代變量。
2. 解析模板
2.1. 搭建項目
項目結構如下,main.go作爲客戶端進行測試,關鍵是process.go實現模板處理邏輯。
go-template-processing/
├── main.go
├── biz
│ └── process.go
└── templates
└── got.tmpl
2.2. 解析模板
首先是解析模板,然後是插值(替換模板中的變量)。Go將包括插值表達式作爲執行模板,後續使用數據進行替換,從而實現數據和模板分離。首先定義process
方法:
package biz
import (
"bytes"
"text/template"
)
func process(t *template.Template, vars interface{}) string {
var tmplBytes bytes.Buffer
err := t.Execute(&tmplBytes, vars)
if err != nil {
panic(err)
}
return tmplBytes.String()
}
該方法幾乎是自解釋,比較容易理解。參數vars是空interface,所以可以是任意數據類型,如map或Struct,只要包括模板表達式中的變量。如果找不對應的變量則輸出結果爲<no value>
,或解析錯誤拋異常。
該方法傳入Template指針,後續方法可以重用。
2.3. 處理字符串模板
下面函數用於處理字符串模板,通過New方法創建模板用於解析str參數。處理結果賦給tmpl,其中處理國際調用前面的process方法。
func ProcessString(str string, vars interface{}) string {
tmpl, err := template.New("tmpl").Parse(str)
if err != nil {
panic(err)
}
return process(tmpl, vars)
}
2.4. 處理模板文件
該函數與ProcessString模板類似,只是處理模板文件:
func ProcessFile(fileName string, vars interface{}) string {
tmpl, err := template.ParseFiles(fileName)
if err != nil {
panic(err)
}
return process(tmpl, vars)
}
ParseFiles
函數接收多個文件名作爲參數,這裏僅解析一個文件。
兩個處理函數定義好,下面開始測試。
2.5. 變量測試
首先在main.go中定義testVar
方法:
func testVar() {
// data structure the template will be applied to
vars := make(map[string]interface{})
vars["Product"] = "Books"
vars["Company"] = "DangDang"
vars["ProductList"] = []string{"Brave", "Loyal"}
// process a template string
resultA := biz.ProcessString("{{.Product}} of {{.Company}}", vars)
// process a template file
resultB := biz.ProcessFile("templates/got.tmpl", vars)
fmt.Println(resultA)
fmt.Println(resultB)
}
然後再main方法中調用:
func main() {
testVar()
}
運行輸出結果爲:
Books of DangDang
Books of DangDang
ProductList:
* Brave
* Loyal
字符串模板和文件模板都解析成功。解析結果可以作爲郵件內容、文件內容等。
2.6. Struct測試
前面提及參數爲interface,既然變量可以,Struct也應該能適用。
我們定義結構體作爲參數進行解析:
func testStruct() {
// using a Struct
type ProductInfo struct {
Product string
Company string
ProductList []string
}
huaWeiStr := ProductInfo{"MobilePhone", "HuaWei", []string{"Mate 30", "Nova 7"}}
resultC := biz.ProcessFile("templates/got.tmpl", huaWeiStr)
fmt.Println(resultC)
}
在main方法中調用該函數輸出:
MobilePhone of HuaWei
ProductList:
* Mate 30
* Nova 7
3. 總結
使用Golang的默認模板非常直接、簡單。本文僅介紹一部分內容,更多內容請參考Go官網模板包。