update tw

This commit is contained in:
chai2010
2015-12-18 10:53:03 +08:00
parent 510c741a6f
commit c66a96ee52
106 changed files with 864 additions and 864 deletions

View File

@@ -1,9 +1,9 @@
## 12.2. reflect.Type和reflect.Value
反射是由 reflect 包提供支持. 它定義了兩重要的類型, Type 和 Value. 一 Type 示一Go類型. 它是一接口, 有許多方法來區分類型和檢査它們的組件, 例如一結構體的成員或一函數的參數等. 唯一能反映 reflect.Type 實現的是接口的類型描述信息(§7.5), 樣的實體標識了動態類型的接口值.
反射是由 reflect 包提供支持. 它定義了兩重要的類型, Type 和 Value. 一 Type 示一Go類型. 它是一接口, 有許多方法來區分類型和檢査它們的組件, 例如一結構體的成員或一函數的參數等. 唯一能反映 reflect.Type 實現的是接口的類型描述信息(§7.5), 樣的實體標識了動態類型的接口值.
函數 reflect.TypeOf 接受任意的 interface{} 類型, 返迴對應動態類型的reflect.Type:
函數 reflect.TypeOf 接受任意的 interface{} 類型, 返迴對應動態類型的reflect.Type:
```Go
t := reflect.TypeOf(3) // a reflect.Type
@@ -11,22 +11,22 @@ fmt.Println(t.String()) // "int"
fmt.Println(t) // "int"
```
其中 TypeOf(3) 調用將值 3 作爲 interface{} 類型參數傳入. 迴到 7.5節 的將一具體的值轉爲接口類型會有一隱式的接口轉換操作, 它會創建一包含兩信息的接口值: 操作數的動態類型(這裡是int)和它的動態的值(這裡是3).
其中 TypeOf(3) 調用將值 3 作爲 interface{} 類型參數傳入. 迴到 7.5節 的將一具體的值轉爲接口類型會有一隱式的接口轉換操作, 它會創建一包含兩信息的接口值: 操作數的動態類型(這裡是int)和它的動態的值(這裡是3).
因爲 reflect.TypeOf 返迴的是一動態類型的接口值, 它總是返迴具體的類型. 因此, 下的代碼將打印 "*os.File" 而不是 "io.Writer". 稍後, 我們將看到 reflect.Type 是具有識別接口類型的達方式功能的.
因爲 reflect.TypeOf 返迴的是一動態類型的接口值, 它總是返迴具體的類型. 因此, 下的代碼將打印 "*os.File" 而不是 "io.Writer". 稍後, 我們將看到 reflect.Type 是具有識別接口類型的達方式功能的.
```Go
var w io.Writer = os.Stdout
fmt.Println(reflect.TypeOf(w)) // "*os.File"
```
要註意的是 reflect.Type 接口是滿足 fmt.Stringer 接口的. 因爲打印動態類型值對於調試和日誌是有幫助的, fmt.Printf 提供了一簡短的 %T 標誌參數, 內部使用 reflect.TypeOf 的結果輸齣:
要註意的是 reflect.Type 接口是滿足 fmt.Stringer 接口的. 因爲打印動態類型值對於調試和日誌是有幫助的, fmt.Printf 提供了一簡短的 %T 標誌參數, 內部使用 reflect.TypeOf 的結果輸齣:
```Go
fmt.Printf("%T\n", 3) // "int"
```
reflect 包中另一重要的類型是 Value. 一 reflect.Value 可以持有一任意類型的值. 函數 reflect.ValueOf 接受任意的 interface{} 類型, 返迴對應動態類型的reflect.Value. 和 reflect.TypeOf 類似, reflect.ValueOf 返迴的結果也是對於具體的類型, 但是 reflect.Value 也可以持有一接口值.
reflect 包中另一重要的類型是 Value. 一 reflect.Value 可以持有一任意類型的值. 函數 reflect.ValueOf 接受任意的 interface{} 類型, 返迴對應動態類型的reflect.Value. 和 reflect.TypeOf 類似, reflect.ValueOf 返迴的結果也是對於具體的類型, 但是 reflect.Value 也可以持有一接口值.
```Go
v := reflect.ValueOf(3) // a reflect.Value
@@ -35,7 +35,7 @@ fmt.Printf("%v\n", v) // "3"
fmt.Println(v.String()) // NOTE: "<int Value>"
```
和 reflect.Type 類似, reflect.Value 也滿足 fmt.Stringer 接口, 但是除非 Value 持有的是字符串, 否則 String 隻是返迴具體的類型. 相, 使用 fmt 包的 %v 標誌參數, 將使用 reflect.Values 的結果格式化.
和 reflect.Type 類似, reflect.Value 也滿足 fmt.Stringer 接口, 但是除非 Value 持有的是字符串, 否則 String 隻是返迴具體的類型. 相, 使用 fmt 包的 %v 標誌參數, 將使用 reflect.Values 的結果格式化.
調用 Value 的 Type 方法將返迴具體類型所對應的 reflect.Type:
@@ -44,7 +44,7 @@ t := v.Type() // a reflect.Type
fmt.Println(t.String()) // "int"
```
逆操作是調用 reflect.ValueOf 對應的 reflect.Value.Interface 方法. 它返迴一 interface{} 類型示 reflect.Value 對應類型的具體值:
逆操作是調用 reflect.ValueOf 對應的 reflect.Value.Interface 方法. 它返迴一 interface{} 類型示 reflect.Value 對應類型的具體值:
```Go
v := reflect.ValueOf(3) // a reflect.Value
@@ -53,9 +53,9 @@ i := x.(int) // an int
fmt.Printf("%d\n", i) // "3"
```
reflect.Value 和 interface{} 都能保存任意的值. 所不的是, 一空的接口隱藏了值對應的示方式和所有的公開的方法, 因此隻有我們知道具體的動態類型纔能使用類型斷言來訪問內部的值(就像上那樣), 對於內部值沒有特別可做的事情. 相比之下, 一 Value 則有很多方法來檢査其內容, 無論它的具體類型是什. 讓我們再次嘗試實現我們的格式化函數 format.Any.
reflect.Value 和 interface{} 都能保存任意的值. 所不的是, 一空的接口隱藏了值對應的示方式和所有的公開的方法, 因此隻有我們知道具體的動態類型纔能使用類型斷言來訪問內部的值(就像上那樣), 對於內部值沒有特別可做的事情. 相比之下, 一 Value 則有很多方法來檢査其內容, 無論它的具體類型是什. 讓我們再次嘗試實現我們的格式化函數 format.Any.
我們使用 reflect.Value 的 Kind 方法來替代之前的類型 switch. 雖然還是有無窮多的類型, 但是它們的kinds類型卻是有限的: Bool, String 和 所有數字類型的基礎類型; Array 和 Struct 對應的聚類型; Chan, Func, Ptr, Slice, 和 Map 對應的引用類似; 接口類型; 還有示空值的無效類型. (空的 reflect.Value 對應 Invalid 無效類型.)
我們使用 reflect.Value 的 Kind 方法來替代之前的類型 switch. 雖然還是有無窮多的類型, 但是它們的kinds類型卻是有限的: Bool, String 和 所有數字類型的基礎類型; Array 和 Struct 對應的聚類型; Chan, Func, Ptr, Slice, 和 Map 對應的引用類似; 接口類型; 還有示空值的無效類型. (空的 reflect.Value 對應 Invalid 無效類型.)
```Go
gopl.io/ch12/format
@@ -96,7 +96,7 @@ func formatAtom(v reflect.Value) string {
}
```
到目前未知, 我們的函數將每值視作一不可分割沒有內部結構的, 因此它叫 formatAtom. 對於聚類型(結構體和數組)接口隻是打印類型的值, 對於引用類型(channels, functions, pointers, slices, 和 maps), 它十六進製打印類型的引用地址. 雖然還不夠理想, 但是依然是一重大的進步, 且 Kind 隻關心底層示, format.Any 也支持新命名的類型. 例如:
到目前未知, 我們的函數將每值視作一不可分割沒有內部結構的, 因此它叫 formatAtom. 對於聚類型(結構體和數組)接口隻是打印類型的值, 對於引用類型(channels, functions, pointers, slices, 和 maps), 它十六進製打印類型的引用地址. 雖然還不夠理想, 但是依然是一重大的進步, 且 Kind 隻關心底層示, format.Any 也支持新命名的類型. 例如:
```Go
var x int64 = 1