2 回答

TA貢獻1886條經驗 獲得超2個贊
這本書關于“保護表示免受無意更新”的解釋對我來說似乎具有誤導性。無論errorString是結構體還是字符串,錯誤信息仍然是字符串并且字符串是不可變的規范。
這也不是關于獨特性的辯論。例如,errors.New("EOF") == io.EOF計算結果為false,盡管兩個錯誤具有完全相同的基礎消息。即使errorString是字符串,只要errors.New返回指向它的指針,同樣適用(參見我的示例。)
您可以說結構體實現error是慣用的,因為這也是標準庫引入自定義錯誤的方式。SyntaxError從encoding/json包裝上看:
type SyntaxError struct {
Offset int64 // error occurred after reading Offset bytes
// contains filtered or unexported fields
}
func (e *SyntaxError) Error() string { return e.msg }
此外,實現error接口的結構沒有性能影響,并且不會比字符串實現消耗更多內存。請參閱Go 數據結構。

TA貢獻1786條經驗 獲得超11個贊
您的 testerr 包運行良好,但它失去了“基于結構的”標準錯誤包的一個主要功能:不等式:
package main
import ( "fmt"; "testerr"; "errors" )
func main() {
a := testerr.New("foo")
b := testerr.New("foo")
fmt.Println(a == b) // true
c := errors.New("foo")
d := errors.New("foo")
fmt.Println(c == d) // false
}
隨著errorString作為一個普通的字符串相同的字符串內容不同的錯誤相等。原始代碼使用一個指向 struct 的指針,并且每個都New分配一個新的 struct,因此New如果與==相同的錯誤文本進行比較,則返回的不同值是不同的。
不允許編譯器在此處生成相同的指針。而“對 New 的不同調用會產生不同的錯誤值”這一特性對于防止意外的錯誤相等很重要。您可以通過*errorString執行來修改您的測試器以產生此屬性Error。試試看:你需要一個臨時取的地址?!案杏X”不對??梢韵胂笠粋€花哨的編譯器,它內部化字符串值并可能返回相同的指針(因為它指向相同的內部化字符串),這會破壞這個很好的不等式屬性。
- 2 回答
- 0 關注
- 364 瀏覽
添加回答
舉報