mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-11-11 06:21:34 +00:00
回到简体
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
## 12.1. 爲何需要反射?
|
||||
## 12.1. 为何需要反射?
|
||||
|
||||
有時候我們需要編寫一個函數能夠處理一類併不滿足普通公共接口的類型的值,也可能是因爲它們併沒有確定的表示方式,或者是在我們設計該函數的時候還這些類型可能還不存在,各種情況都有可能。
|
||||
有时候我们需要编写一个函数能够处理一类并不满足普通公共接口的类型的值,也可能是因为它们并没有确定的表示方式,或者是在我们设计该函数的时候还这些类型可能还不存在,各种情况都有可能。
|
||||
|
||||
一個大家熟悉的例子是fmt.Fprintf函數提供的字符串格式化處理邏輯,它可以用例對任意類型的值格式化併打印,甚至支持用戶自定義的類型。讓我們也來嚐試實現一個類似功能的函數。爲了簡單起見,我們的函數隻接收一個參數,然後返迴和fmt.Sprint類似的格式化後的字符串。我們實現的函數名也叫Sprint。
|
||||
一个大家熟悉的例子是fmt.Fprintf函数提供的字符串格式化处理逻辑,它可以用例对任意类型的值格式化并打印,甚至支持用户自定义的类型。让我们也来尝试实现一个类似功能的函数。为了简单起见,我们的函数只接收一个参数,然后返回和fmt.Sprint类似的格式化后的字符串。我们实现的函数名也叫Sprint。
|
||||
|
||||
我們使用了switch類型分支首先來測試輸入參數是否實現了String方法,如果是的話就使用該方法。然後繼續增加類型測試分支,檢査是否是每個基於string、int、bool等基礎類型的動態類型,併在每種情況下執行相應的格式化操作。
|
||||
我们使用了switch类型分支首先来测试输入参数是否实现了String方法,如果是的话就使用该方法。然后继续增加类型测试分支,检查是否是每个基于string、int、bool等基础类型的动态类型,并在每种情况下执行相应的格式化操作。
|
||||
|
||||
```Go
|
||||
func Sprint(x interface{}) string {
|
||||
@@ -31,6 +31,6 @@ func Sprint(x interface{}) string {
|
||||
}
|
||||
```
|
||||
|
||||
但是我們如何處理其它類似[]float64、map[string][]string等類型呢?我們當然可以添加更多的測試分支,但是這些組合類型的數目基本是無窮的。還有如何處理url.Values等命名的類型呢?雖然類型分支可以識别出底層的基礎類型是map[string][]string,但是它併不匹配url.Values類型,因爲它們是兩種不同的類型,而且switch類型分支也不可能包含每個類似url.Values的類型,這會導致對這些庫的循環依賴。
|
||||
但是我们如何处理其它类似[]float64、map[string][]string等类型呢?我们当然可以添加更多的测试分支,但是这些组合类型的数目基本是无穷的。还有如何处理url.Values等命名的类型呢?虽然类型分支可以识别出底层的基础类型是map[string][]string,但是它并不匹配url.Values类型,因为它们是两种不同的类型,而且switch类型分支也不可能包含每个类似url.Values的类型,这会导致对这些库的循环依赖。
|
||||
|
||||
沒有一種方法來檢査未知類型的表示方式,我們被卡住了。這就是我們爲何需要反射的原因。
|
||||
没有一种方法来检查未知类型的表示方式,我们被卡住了。这就是我们为何需要反射的原因。
|
||||
|
||||
Reference in New Issue
Block a user