W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
原文鏈接:https://gopl-zh.github.io/ch12/ch12-01.html
有時(shí)候我們需要編寫(xiě)一個(gè)函數(shù)能夠處理一類(lèi)并不滿足普通公共接口的類(lèi)型的值,也可能是因?yàn)樗鼈儾](méi)有確定的表示方式,或者是在我們?cè)O(shè)計(jì)該函數(shù)的時(shí)候這些類(lèi)型可能還不存在。
一個(gè)大家熟悉的例子是fmt.Fprintf函數(shù)提供的字符串格式化處理邏輯,它可以用來(lái)對(duì)任意類(lèi)型的值格式化并打印,甚至支持用戶自定義的類(lèi)型。讓我們也來(lái)嘗試實(shí)現(xiàn)一個(gè)類(lèi)似功能的函數(shù)。為了簡(jiǎn)單起見(jiàn),我們的函數(shù)只接收一個(gè)參數(shù),然后返回和fmt.Sprint類(lèi)似的格式化后的字符串。我們實(shí)現(xiàn)的函數(shù)名也叫Sprint。
我們首先用switch類(lèi)型分支來(lái)測(cè)試輸入?yún)?shù)是否實(shí)現(xiàn)了String方法,如果是的話就調(diào)用該方法。然后繼續(xù)增加類(lèi)型測(cè)試分支,檢查這個(gè)值的動(dòng)態(tài)類(lèi)型是否是string、int、bool等基礎(chǔ)類(lèi)型,并在每種情況下執(zhí)行相應(yīng)的格式化操作。
func Sprint(x interface{}) string {
type stringer interface {
String() string
}
switch x := x.(type) {
case stringer:
return x.String()
case string:
return x
case int:
return strconv.Itoa(x)
// ...similar cases for int16, uint32, and so on...
case bool:
if x {
return "true"
}
return "false"
default:
// array, chan, func, map, pointer, slice, struct
return "???"
}
}
但是我們?nèi)绾翁幚砥渌?lèi)似[]float64、map[string][]string等類(lèi)型呢?我們當(dāng)然可以添加更多的測(cè)試分支,但是這些組合類(lèi)型的數(shù)目基本是無(wú)窮的。還有如何處理類(lèi)似url.Values這樣的具名類(lèi)型呢?即使類(lèi)型分支可以識(shí)別出底層的基礎(chǔ)類(lèi)型是map[string][]string,但是它并不匹配url.Values類(lèi)型,因?yàn)樗鼈兪莾煞N不同的類(lèi)型,而且switch類(lèi)型分支也不可能包含每個(gè)類(lèi)似url.Values的類(lèi)型,這會(huì)導(dǎo)致對(duì)這些庫(kù)的依賴。
沒(méi)有辦法來(lái)檢查未知類(lèi)型的表示方式,我們被卡住了。這就是我們需要反射的原因。
![]() | ![]() |
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: