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。试试看:你需要一个临时取的地址。“感觉”不对。可以想象一个花哨的编译器,它内部化字符串值并可能返回相同的指针(因为它指向相同的内部化字符串),这会破坏这个很好的不等式属性。
- 2 回答
- 0 关注
- 312 浏览
添加回答
举报