亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么 errorString 是一個結構體,而不是一個字符串

為什么 errorString 是一個結構體,而不是一個字符串

Go
桃花長相依 2021-11-29 16:38:08
我正在閱讀 The Go Programming Language 一書,并在其中描述了錯誤包和接口package errorstype 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使用 a實現的測試代碼string。請注意,當嘗試從另一個包中使用它時,您不能僅將字符串分配為錯誤。package testerrtype Error interface {        Error() string}func New(text string) Error {        return errorString(text)}type errorString stringfunc (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)當然,這有一個缺點,因為碰巧具有相同錯誤字符串的不同錯誤將評估為相等,這是我們不想要的。
查看完整描述

2 回答

?
MM們

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 數據結構。


查看完整回答
反對 回復 2021-11-29
?
Qyouu

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”不對??梢韵胂笠粋€花哨的編譯器,它內部化字符串值并可能返回相同的指針(因為它指向相同的內部化字符串),這會破壞這個很好的不等式屬性。


查看完整回答
反對 回復 2021-11-29
  • 2 回答
  • 0 關注
  • 364 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號