如果我在 Golang 中撰寫一個泛型函式,我可以像這樣列印函式的任何一個引數的型別,這提供了對型別引數的一些了解:
func foo[T any](a T, b T) string {
return fmt.Sprintf("%v and %v are of type %T", a, b, a)
}
但是,如果我修改函式以取而代之的是:
func foo[T any](args ...T) string {
return fmt.Sprintf("% v are of type %T", args, args)
}
這不會列印我更喜歡的內容,因為呼叫foo[int]意味著它args有一種型別,[]int而我想列印int。我可以將其修改為列印args[0],但這意味著我還必須檢查其中args為空的情況,在這種情況下,我沒有辦法獲取args. 我也可以使用反射來獲取型別,但由于它是一個通用函式,我也應該在編譯時知道這一點。
有沒有一種方法可以在編譯時獲得名稱,T而無需列印任何引數的型別或通過反射?
uj5u.com熱心網友回復:
有沒有一種方法可以在編譯時獲取 T 的名稱,而無需列印任何引數的型別或通過反射?
不
你需要對此進行反思。
uj5u.com熱心網友回復:
無法在編譯時列印型別名稱。fmt和reflect函式(使用)都是fmt運行時操作。您可能能夠通過靜態分析找出某些運算式的型別,但這與運行時列印是正交的。
無論如何,在運行時,如果型別引數串列捕獲了復合型別的基型別,包括可變引數切片,您可以通過宣告該型別的新變數來簡單地列印它。該成語*new(T)特別允許使用單行符來做到這一點:
func foo[T any](args ...T) string {
return fmt.Sprintf("% v are of type %T", args, *new(T))
}
現在呼叫它foo(1,2,3)會給出字串:
"[1 2 3] are of type int"
是的,編譯器足夠聰明,知道*new(T)不會逃到堆中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/494534.html
上一篇:迭代列舉引數的型別
下一篇:從可選建構式引數推斷的類屬性
