簡體   English   中英

文本/模板如何確定地圖的“默認文本表示”?

[英]How does text/template determine the “default textual representation” of a map?

根據Go標准庫中的text/template包的文檔 ,(據我所知, html/template在這里是相同的)簡單地使用管道操作符將吐出任何不同的“默認文本表示”:

{{管道}}

 The default textual representation of the value of the pipeline is copied to the output. 

在地圖的情況下,你會得到一個很好的打印格式,其中包含鍵名和所有內容......順便說一句,這是有效的JavaScript,因此如果你願意,它可以很容易地將整個結構傳遞給你的JS代碼。

我的問題是,這個文本表示是如何確定的,更具體地說,我可以加入它嗎? 我想也許它會檢查管道是否是fmt.Stringer ,我可以給我的map子類型一個String() string方法,但似乎並非如此。 我正在尋找text/template代碼,但我似乎不知道它是如何做到的。

text/template如何確定“默認文本表示”?

默認文本表示由fmt包打印值的方式決定。 所以你正在吠叫正確的樹。

看這個例子:

t := template.Must(template.New("").Parse("{{.}}"))
m := map[string]interface{}{"a": "abc", "b": 2}
t.Execute(os.Stdout, m)

它輸出:

map[a:abc b:2]

現在,如果我們使用帶有String()方法的自定義地圖類型:

type MyMap map[string]interface{}

func (m MyMap) String() string { return "custom" }

mm := MyMap{"a": "abc", "b": 2}
t.Execute(os.Stdout, mm)

輸出是:

custom

Go Playground上試試這些(及以下示例)。

需要注意什么?

請注意, MyMap.String()有一個值接收器(不是指針)。 我傳遞了MyMap的值,所以它有效。 如果將接收器類型更改為指向MyMap指針,則它將不起作用。 這是因為只有*MyMap類型的值才會有String()方法,而不是MyMap的值。

如果String()方法有一個指針接收器,如果希望自定義表示工作,則必須傳遞&mm (類型為*MyMap的值)。

另請注意,在html/template情況下,模板引擎執行上下文轉義,因此fmt包的結果可能會被進一步轉義。

例如,如果您的自定義String()方法將返回“不安全”的內容:

func (m MyMap2) String() string { return "<html>" }

試圖插入它:

mm2 := MyMap2{"a": "abc", "b": 2}
t.Execute(os.Stdout, mm2)

獲取轉義:

&lt;html&gt;

履行

這是在text/template包中實現的地方: text/template/exec.go ,unexported function state.PrintValue() ,當前行#848:

_, err := fmt.Fprint(s.wr, iface)

如果你正在使用html/template包,它是用html/template/content.go ,未實現的函數stringify() ,當前第135行:

return fmt.Sprint(args...), contentTypePlain

更多選擇

另請注意,如果值實現error ,將調用Error()方法,它優先於String()

type MyMap map[string]interface{}

func (m MyMap) Error() string { return "custom-error" }

func (m MyMap) String() string { return "custom" }

t := template.Must(template.New("").Parse("{{.}}"))
mm := MyMap{"a": "abc", "b": 2}
t.Execute(os.Stdout, mm)

將輸出:

custom-error

而不是custom Go Playground嘗試一下。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM