dsrbb20862 2015-12-17 12:53
浏览 63
已采纳

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

I am reading The Go Programming Language book and in it's description of the error package and the interface

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 }

it says

The underlying type of errorString is a struct, not a string, to protect its representation from inadvertent (or premeditated) updates.

What does this mean? Wouldn't the package hide the underlying type since errorString isn't exported?

Update Here is the test code I used implementing errorString using a string instead. Note that when try to use it from another package, you can't just assign a string as an error.

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

And testing it with the suggested codes

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

Will end up producing an error when compiling

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

Of course there is a downside to this since different errors that happen to have the same error string will evaluate to being equal which we don't want.

  • 写回答

2条回答 默认 最新

  • dongsha9208 2015-12-17 13:14
    关注

    The book's explanation about "protecting representation from inadvertent updates" looks misleading to me. Whether errorString is a struct or a string, the error message is still a string and a string is immutable by specification.

    This isn't a debate about uniqueness either. For example, errors.New("EOF") == io.EOF evaluates to false, although both errors have the exact same underlying message. The same would apply even if errorString was a string, as long as errors.New would return a pointer to it (see my example.)

    You could say a struct implementing error is idiomatic since that's also how the standard library introduces custom errors. Take a look at SyntaxError from the encoding/json package:

    type SyntaxError struct {
            Offset int64 // error occurred after reading Offset bytes
            // contains filtered or unexported fields
    }
    
    func (e *SyntaxError) Error() string { return e.msg }
    

    (source)

    Also, a struct implementing the error interface has no performance implications and does not consume more memory over a string implementation. See Go Data Structures.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 Macbookpro 连接热点正常上网,连接不了Wi-Fi。
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 linux驱动,linux应用,多线程
  • ¥20 我要一个分身加定位两个功能的安卓app
  • ¥15 基于FOC驱动器,如何实现卡丁车下坡无阻力的遛坡的效果
  • ¥15 IAR程序莫名变量多重定义