亚洲熟女综合色一区二区三区,亚洲精品中文字幕无码蜜桃,亚洲va欧美va日韩va成人网,亚洲av无码国产一区二区三区,亚洲精品无码久久久久久久

深入淺出標(biāo)準(zhǔn)庫 text/template 包

go 語言標(biāo)準(zhǔn)庫 text/template 在 web 編程項(xiàng)目中經(jīng)常用到,本文詳細(xì)介紹了這個包的用法。

官方定義:

Package template implements data-driven templates for generating textual output.

template 包是數(shù)據(jù)驅(qū)動的文本輸出模板,其實(shí)就是在寫好的模板中填充數(shù)據(jù)。

模板

什么是模板?

下面是一個簡單的模板示例:

深入淺出標(biāo)準(zhǔn)庫 text/template 包

{{ 和 }} 中間的句號?.?代表傳入模板的數(shù)據(jù),根據(jù)傳入的數(shù)據(jù)不同渲染不同的內(nèi)容。

.?可以代表 go 語言中的任何類型,如結(jié)構(gòu)體、哈希等。

至于 {{ 和 }} 包裹的內(nèi)容統(tǒng)稱為 action,分為兩種類型:

  • 數(shù)據(jù)求值(data evaluations)
  • 控制結(jié)構(gòu)(control structures)

action 求值的結(jié)果會直接復(fù)制到模板中,控制結(jié)構(gòu)和我們寫 Go 程序差不多,也是條件語句、循環(huán)語句、變量、函數(shù)調(diào)用等等。..

將模板成功解析(Parse)后,可以安全地在并發(fā)環(huán)境中使用,如果輸出到同一個?io.Writer?數(shù)據(jù)可能會重疊(因?yàn)椴荒鼙WC并發(fā)執(zhí)行的先后順序)。

Actions

模板中的 action 并不多,我們一個一個看。

注釋

深入淺出標(biāo)準(zhǔn)庫 text/template 包

裁剪空格

深入淺出標(biāo)準(zhǔn)庫 text/template 包

文本輸出

深入淺出標(biāo)準(zhǔn)庫 text/template 包

pipeline 代表的數(shù)據(jù)會產(chǎn)生與調(diào)用?fmt.Print?函數(shù)類似的輸出,例如整數(shù)類型的 3 會轉(zhuǎn)換成字符串 "3" 輸出。

條件語句

深入淺出標(biāo)準(zhǔn)庫 text/template 包

如果 pipeline 的值為空,不會輸出 T1,除此之外 T1 都會被輸出。

空值有 false、0、任意 nil 指針、接口值、數(shù)組、切片、字典和空字符串?""(長度為 0 的字符串)。

循環(huán)語句

深入淺出標(biāo)準(zhǔn)庫 text/template 包

pipeline 的值必須是數(shù)組、切片、字典和通道中的一種,即可迭代類型的值,根據(jù)值的長度輸出多個 T1。

define

深入淺出標(biāo)準(zhǔn)庫 text/template 包

定義命名為 name 的模板。

template

深入淺出標(biāo)準(zhǔn)庫 text/template 包

引用命名為 name 的模板。

block

深入淺出標(biāo)準(zhǔn)庫 text/template 包

block 的語義是如果有命名為 name 的模板,就引用過來執(zhí)行,如果沒有命名為 name 的模板,就是執(zhí)行自己定義的內(nèi)容。

也就是多做了一步模板是否存在的判斷,根據(jù)這個結(jié)果渲染不同的內(nèi)容。

with

深入淺出標(biāo)準(zhǔn)庫 text/template 包

with 創(chuàng)建一個新的上下文環(huán)境,在此環(huán)境中的?.?與外面的?.?無關(guān)。

參數(shù)

參數(shù)的值有多種表現(xiàn)形式,可以求值任何類型,包括函數(shù)、指針(指針會自動間接取值到原始的值):

  • 布爾、字符串、字符、浮點(diǎn)數(shù)、復(fù)數(shù)的行為和 Go 類似
  • 關(guān)鍵字?nil?代表 go 語言中的?nil
  • 字符句號 . 代表值的結(jié)果
  • 以 $ 字符開頭的變量則為變量對應(yīng)的值
  • 結(jié)構(gòu)體的字段表示為?.Field,結(jié)果是 Field 的值,支持鏈?zhǔn)秸{(diào)用?.Field1.Field2
  • 字典的 key 表示為?.Key?結(jié)果是 Key 對應(yīng)的值
  • 如果是結(jié)構(gòu)體的方法集中的方法 .Method 結(jié)果是方法調(diào)用后返回的值(The result is the value of invoking the method with dot as the receiver)**
    • 方法要么只有一個任意類型的返回值要么第二個返回值為 error,不能再多了,如果 error 不為 nil,會直接報(bào)錯,停止模板渲染
    • 方法調(diào)用的結(jié)果可以繼續(xù)鏈?zhǔn)秸{(diào)用?.Field1.Key1.Method1.Field2.Key2.Method2
    • 聲明變量方法集也可以調(diào)用?$x.Method1.Field
    • 用括號將調(diào)用分組?print (.Func1 arg1) (.Func2 arg2)?或?(.StructValuedMethod "arg").Field

這里最難懂的可能就是函數(shù)被調(diào)用的方式,如果訪問結(jié)構(gòu)體方法集中的函數(shù)和字段中的函數(shù),此時的行為有什么不同?

寫個 demo 測一下:

深入淺出標(biāo)準(zhǔn)庫 text/template 包

可以得出結(jié)論:如果函數(shù)是結(jié)構(gòu)體中的函數(shù)字段,該函數(shù)不會自動調(diào)用,只能使用內(nèi)置函數(shù)?call?調(diào)用。

如果函數(shù)是結(jié)構(gòu)體方法集中的方法,會自動調(diào)用該方法,并且會將返回值賦值給?.,如果函數(shù)返回新的結(jié)構(gòu)體、map,可以繼續(xù)鏈?zhǔn)秸{(diào)用。

變量

action 中的 pipeline 可以初始化變量存儲結(jié)果,語法也很簡單:

深入淺出標(biāo)準(zhǔn)庫 text/template 包

此時,這個 action 聲明了一個變量而沒有產(chǎn)生任何輸出。

range 循環(huán)可以聲明兩個變量:

深入淺出標(biāo)準(zhǔn)庫 text/template 包

在 if、with 和 range 中,變量的作用域拓展到 {{ end }} 所在的位置。

如果不是控制結(jié)構(gòu),聲明的變量的作用域會擴(kuò)展到整個模板。

例如在模板開始時聲明變量:

深入淺出標(biāo)準(zhǔn)庫 text/template 包

在渲染開始的時候,$?變量會被替換成?.?開頭的值,例如?$pages?會被替換成?.pagenation.Pages。所以在模板間的相互引用不會傳遞變量,變量只在某個特定的作用域中產(chǎn)生作用。

函數(shù)

模板渲染時會在兩個地方查找函數(shù):

  • 自定義的函數(shù) map
  • 全局函數(shù) map,這些函數(shù)是模板內(nèi)置的

自定義函數(shù)使用?func (t *Template) Funcs(funcMap FuncMap) *Template?注冊。

全局函數(shù)列表:

and

返回參數(shù)之間 and 布爾操作的結(jié)果,其實(shí)就是 JavaScript 中的邏輯操作符?&&,返回第一個能轉(zhuǎn)換成 false 的值,在 Go 中就是零值,如果都為 true 返回最后一個值。

深入淺出標(biāo)準(zhǔn)庫 text/template 包

or

邏輯操作符?||,返回第一個能轉(zhuǎn)換成 true 的值,在 Go 中就是非零值,如果都為 false 返回最后一個值。

深入淺出標(biāo)準(zhǔn)庫 text/template 包

call

返回調(diào)用第一個函數(shù)參數(shù)的結(jié)果,函數(shù)必須有一個或兩個回值(第二個返回值必須是 error,如果值不為 nil 會停止模板渲染)

深入淺出標(biāo)準(zhǔn)庫 text/template 包

html

返回轉(zhuǎn)義后的 HTML 字符串,這個函數(shù)不能在?html/template?中使用。

js

返回轉(zhuǎn)義后的 JavaScript 字符串。

index

在第一個參數(shù)是 array、slice、map 時使用,返回對應(yīng)下標(biāo)的值。

index x 1 2 3?等于?x[1][2][3]。

len

返回復(fù)合類型的長度。

not

返回布爾類型參數(shù)的相反值。

print

等于?fmt.Sprint。

printf

等于?fmt.Sprintf。

println

等于?fmt.Sprintln。

urlquery

對字符串進(jìn)行 url Query 轉(zhuǎn)義,不能在?html/template?包中使用。

深入淺出標(biāo)準(zhǔn)庫 text/template 包

從源碼可以看到這個函數(shù)直接調(diào)用?url.QueryEscape?對字符串進(jìn)行轉(zhuǎn)義,并沒有什么神秘的。

比較函數(shù)

  • eq: ==
  • ge: >=
  • gt: >
  • le: <=
  • lt: <
  • ne: !=

分析兩個源碼:

深入淺出標(biāo)準(zhǔn)庫 text/template 包

深入淺出標(biāo)準(zhǔn)庫 text/template 包

eq 先判斷接口類型是否相等,然后判斷值是否相等,沒什么特殊的地方。

ne 更是簡單的調(diào)用 eq,然后取反。

ge、gt、le、lt 與 eq 類似,先判斷類型,然后判斷大小。

嵌套模板

下面是一個更復(fù)雜的例子:

深入淺出標(biāo)準(zhǔn)庫 text/template 包

ExecuteTemplate?指定的名字就是模板文件中?define "name"?的 name。

總結(jié)

Parse?系列函數(shù)初始化的?Template?類型實(shí)例。

Execute?系列函數(shù)則將數(shù)據(jù)傳遞給模板渲染最終的字符串。

模板本質(zhì)上就是?Parse?函數(shù)加載多個文件到一個?Tempalte?類型實(shí)例中,解析文件中的 define 關(guān)鍵字注冊命名模板,命名模板之間可以使用?template?互相引用,Execute?傳入對應(yīng)的數(shù)據(jù)渲染。

轉(zhuǎn)自:

juejin.cn/post/6844903762901860360

相關(guān)新聞

歷經(jīng)多年發(fā)展,已成為國內(nèi)好評如潮的Linux云計(jì)算運(yùn)維、SRE、Devops、網(wǎng)絡(luò)安全、云原生、Go、Python開發(fā)專業(yè)人才培訓(xùn)機(jī)構(gòu)!