回到简体

This commit is contained in:
chai2010
2016-02-15 11:06:34 +08:00
parent 9e878f9944
commit 2b37b23285
177 changed files with 2354 additions and 2354 deletions

View File

@@ -1,20 +1,20 @@
## 12.9. 幾點忠告
## 12.9. 几点忠告
然反射提供的API遠多於我們講到的,我前面的例子主要是出了一方向,通反射可以實現哪些功能。反射是一個強大併富有表力的工具,但是它應該被小心地使用,原因有三。
然反射提供的API远多于我们讲到的,我前面的例子主要是出了一方向,通反射可以实现哪些功能。反射是一个强大并富有表力的工具,但是它应该被小心地使用,原因有三。
第一原因是,基反射的代是比脆弱的。對於每一個會導致編譯器報告類型錯誤的問題,在反射中都有之相對應的問題,不同的是編譯器會在構建時馬上報告錯誤,而反射是在眞正運行到的候才會拋出panic常,可能是完代很久之後的時候了,而且程序也可能行了很長的時間
第一原因是,基反射的代是比脆弱的。对于每一个会导致编译器报告类型错误的问题,在反射中都有之相对应的问题,不同的是编译器会在构建时马上报告错误,而反射是在真正运行到的候才会抛出panic常,可能是完代很久之后的时候了,而且程序也可能行了很长的时间
以前面的readList函§12.6例,爲了從輸入讀取字符串填充int型的量而調用的reflect.Value.SetString方法可能致panic常。大多使用反射的程序都有似的風險,需要非常小心地檢査每個reflect.Value的對於值的型、是否可取地址,有是否可以被改等。
以前面的readList函§12.6例,为了从输入读取字符串填充int型的量而用的reflect.Value.SetString方法可能致panic常。大多使用反射的程序都有似的风险,需要非常小心地检查每个reflect.Value的对于值的型、是否可取地址,有是否可以被改等。
避免這種因反射而致的脆弱性的問題的最好方法是所有的反射相的使用控在包的部,如果可能的避免在包的API中直接暴露reflect.Value型,這樣可以限一些非法入。如果法做到這一點,在每個有風險的操作前指向外的類型檢査。以標準庫中的代碼爲例,fmt.Printf收到一非法的操作是,它併不會拋出panic常,而是打印相關的錯誤信息。程序雖然還有BUG但是更加容易診斷
避免这种因反射而致的脆弱性的问题的最好方法是所有的反射相的使用控在包的部,如果可能的避免在包的API中直接暴露reflect.Value型,这样可以限一些非法入。如果法做到这一点,在每个有风险的操作前指向外的类型检查。以标准库中的代码为例,fmt.Printf收到一非法的操作是,它并不会抛出panic常,而是打印相关的错误信息。程序虽然还有BUG但是更加容易诊断
```Go
fmt.Printf("%d %s\n", "hello", 42) // "%!d(string=hello) %!s(int=42)"
```
反射同降低了程序的安全性,還影響了自化重和分析工具的準確性,因爲它們無法識别運行時才能確認的類型信息。
反射同降低了程序的安全性,还影响了自化重和分析工具的准确性,因为它们无法识别运行时才能确认的类型信息。
避免使用反射的第二原因是,卽使對應類型提供了相同文,但是反射的操作不能做靜態類型檢査,而且大量反射的代通常以理解。是需要小心翼翼地爲每個導出的型和其它接受interface{}或reflect.Value類型參數的函數維護説明文
避免使用反射的第二原因是,即使对应类型提供了相同文,但是反射的操作不能做静态类型检查,而且大量反射的代通常以理解。是需要小心翼翼地为每个导出的型和其它接受interface{}或reflect.Value类型参数的函数维护说明文
第三原因,基反射的代通常比正常的代碼運行速度慢一到兩個數量級。對於一個典型的目,大部分函的性能和程序的整性能關繫不大,所以使用反射可能使程序更加清晰。測試是一特别合使用反射的景,因爲每個測試的數據集都很小。但是對於性能關鍵路徑的函,最好避免使用反射。
第三原因,基反射的代通常比正常的代码运行速度慢一到两个数量级。对于一个典型的目,大部分函的性能和程序的整性能关系不大,所以使用反射可能使程序更加清晰。测试是一特别合使用反射的景,因为每个测试的数据集都很小。但是对于性能关键路径的函,最好避免使用反射。