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