当前位置:  开发笔记 > 编程语言 > 正文

为什么errorString是一个结构,而不是一个字符串

如何解决《为什么errorString是一个结构,而不是一个字符串》经验,为你挑选了1个好方法。

我正在阅读The Go Programming Language一书及其对错误包和界面的描述

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 }

它说

errorString的基础类型是结构,而不是字符串,以保护其表示免受无意(或预谋)更新.

这是什么意思?包不会隐藏底层类型,因为errorString没有导出?

更新 这里是我使用实现测试代码errorString使用string来代替.请注意,当尝试从另一个包中使用它时,您不能只将字符串指定为错误.

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) }

并使用建议的代码进行测试

func main() {
    err := errors.New("foo")
    err = "bar"
    fmt.Prinln(err)
}

编译时最终会产生错误

cannot use "bar" (type string) as type testerr.Error in assignment: string does not implement testerr.Error (missing Error method)

当然,这有一个缺点,因为碰巧具有相同错误字符串的不同错误将评估为我们不想要的相等.



1> Moshe Revah..:

该书关于"保护代表免受无意更新"的解释对我来说似乎有误导性.无论errorString是结构还是字符串,错误消息仍然是一个字符串,字符串是不可变的规范.

这也不是关于独特性的争论.例如,errors.New("EOF") == io.EOF求值为false,尽管两个错误都具有完全相同的基础消息.即使errorString是一个字符串也是如此,只要errors.New返回一个指向的指针(参见我的例子).

你可以说结构实现error是惯用的,因为这也是标准库引入自定义错误的方式.SyntaxErrorencoding/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接口的结构没有性能影响,并且不会在字符串实现上消耗更多内存.请参阅转到数据结构.

推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有