Why is errorString a struct, not a string
我正在阅读《 Go编程语言》一书,其中包含错误包和界面的说明
1 2 3 4 5 6 7 8 9 10 11 | package errors type error interface { Error() string } func New(text string) error { return &errorString{text} } type errorString struct { text string } func (e *errorString) Error() string { return e.text } |
它说
The underlying type of errorString is a struct, not a string, to protect its representation from inadvertent (or premeditated) updates.
这是什么意思? 由于未导出
更新资料
这是我用来使用
1 2 3 4 5 6 7 8 9 10 11 12 13 | package testerr type Error interface { Error() string } func New(text string) Error { return errorString(text) } type errorString string func (e errorString) Error() string { return string(e) } |
并使用建议的代码进行测试
1 2 3 4 5 | func main() { err := errors.New("foo") err ="bar" fmt.Prinln(err) } |
编译时最终会产生错误
string does not implement testerr.Error (missing Error method)
当然,这样做有一个缺点,因为碰巧具有相同错误字符串的不同错误将被评估为相等,这是我们不希望的。
这本书对"保护表示免受意外更新的影响"的解释对我来说似乎具有误导性。不管
这也不是关于唯一性的辩论。例如,尽管两个错误都有完全相同的基础消息,但是
您可以说实现
1 2 3 4 5 6 | type SyntaxError struct { Offset int64 // error occurred after reading Offset bytes // contains filtered or unexported fields } func (e *SyntaxError) Error() string { return e.msg } |
(资源)
同样,实现
您的testerr程序包运行良好,但失去了"基于结构"标准错误程序包的主要功能:不平等的功能:
1 2 3 4 5 6 7 8 9 10 11 12 | 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 } |
当
此处不允许任何编译器产生相同的指针。而"对New的不同调用会产生不同的错误值"这一功能对于防止意外的错误相等很重要。您可以通过使