mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-10-28 00:53:09 +00:00
make
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
## 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 {
|
||||
@@ -32,8 +32,8 @@ 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