您好,登錄后才能下訂單哦!
這篇文章主要介紹了go語言eof錯誤指的是什么的相關(guān)知識,內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇go語言eof錯誤指的是什么文章都會有所收獲,下面我們一起來看看吧。
在go語言中,eof是指文件結(jié)尾錯誤,是Go語言中最重要的錯誤變量,存在于io包中,用于表示輸入流的結(jié)尾。因?yàn)槊總€文件都有一個結(jié)尾,所以“io.EOF”很多時候并不能算是一個錯誤,它更重要的是表示一個輸入流結(jié)束了。
golang 文件結(jié)尾錯誤(EOF)
函數(shù)經(jīng)常會返回多種錯誤,這對終端用戶來說可能會很有趣,但對程序而言,這使得情況變得復(fù)雜。很多時候,程序必須根據(jù)錯誤類型,作出不同的響應(yīng)。讓我們考慮這樣一個例子:
從文件中讀取n個字節(jié)。如果n等于文件的長度,讀取過程的任何錯誤都表示失敗。如果n小于文件的長度,調(diào)用者會重復(fù)的讀取固定大小的數(shù)據(jù)直到文件結(jié)束。這會導(dǎo)致調(diào)用者必須分別處理由文件結(jié)束引起的各種錯誤。
基于這樣的原因,io包
保證任何由文件結(jié)束引起的讀取失敗都返回同一個錯誤——io.EOF,該錯誤在io包中定義:
package io
import "errors"
// EOF is the error returned by Read when no more input is available.
var EOF = errors.New("EOF")
認(rèn)識io.EOF
io.EOF是io包中的變量, 表示文件結(jié)束的錯誤:
package io23var EOF = errors.New("EOF")
也通過以下命令查看詳細(xì)文檔:
$ go doc io.EOF
var EOF = errors.New("EOF")
EOF is the error returned by Read when no more input is available. Functions
should return EOF only to signal a graceful end of input. If the EOF occurs
unexpectedly in a structured data stream, the appropriate error is either
ErrUnexpectedEOF or some other error giving more detail.
$
io.EOF大約可以算是Go語言中最重要的錯誤變量了, 它用于表示輸入流的結(jié)尾. 因?yàn)槊總€文件都有一個結(jié)尾, 所以io.EOF很多時候并不能算是一個錯誤, 它更重要的是表示一個輸入流結(jié)束了。
io.EOF設(shè)計(jì)的缺陷
可惜標(biāo)準(zhǔn)庫中的io.EOF的設(shè)計(jì)是有問題的. 首先EOF是End-Of-File的縮寫, 根據(jù)Go語言的習(xí)慣大寫字母縮寫一般表示常量. 可惜io.EOF被錯誤地定義成了變量, 這導(dǎo)致了API權(quán)限的擴(kuò)散. 而最小化API權(quán)限是任何一個模塊或函數(shù)設(shè)計(jì)的最高要求. 通過最小化的權(quán)限, 可以盡早發(fā)現(xiàn)代碼中不必要的錯誤.
比如Go語言一個重要的安全設(shè)計(jì)就是禁止隱式的類型轉(zhuǎn)換. 因此這個設(shè)計(jì)我們就可以很容易發(fā)現(xiàn)程序的BUG. 此外Go語言禁止定義沒有被使用到的局部變量(函數(shù)參數(shù)除外, 因此函數(shù)參數(shù)是函數(shù)接口的一個部分)和禁止導(dǎo)入沒有用到的包都是最小化權(quán)限的最佳實(shí)踐. 這些最小API權(quán)限的設(shè)計(jì)不僅僅改進(jìn)了程序的質(zhì)量, 也提高了編譯工具的性能和輸出的目標(biāo)文件.
因?yàn)镋OF被定義成一個變量, 這導(dǎo)致了該變量可能會被惡意改變. 下面的代碼就是一種優(yōu)雅的埋坑方式:
func init() {2 io.EOF = nil3}
這雖然是一個段子, 但是卻真實(shí)地暴漏了EOF接口的設(shè)計(jì)缺陷: 它存在嚴(yán)重的安全隱患. 變量的類型似乎也在暗示用戶可以放心地修改變量的值. 因此說EOF是一個不安全也不優(yōu)雅的設(shè)計(jì).
io.EOF改為常量
一個顯然的改進(jìn)思路是將io.EOF定義為常量. 但是因?yàn)镋OF對應(yīng)一個表示error接口類型, 而Go語言目前的常量語法并不支持定義常量類型的接口. 但是我們可以通過一些技巧繞過這個限制.
Go語言的常量有bool/int/float/string/nil這幾種主要類型. 常量不僅僅不包含接口等復(fù)雜類型, 甚至連常量的數(shù)組或結(jié)構(gòu)體都不支持! 不過常量有一個重要的擴(kuò)展規(guī)則: 以bool/int/float/string/nil為基礎(chǔ)類型定義的新類型也支持常量.
比如, 我們重新定義一個字符串類型, 它也可以支持常量的:
type MyString string2const name MyString = "chai2010"
這個例子中MyString是一個新定義的類型, 可以定義這種類型的常量, 因?yàn)樗牡讓拥膕tring類型是支持常量的.
那么io.EOF的底層類型是什么呢? EOF是通過errors.New("EOF")定義的, 下面是這個函數(shù)的實(shí)現(xiàn):
package errors
// New returns an error that formats as the given text.
func New(text string) error {
return &errorString{text}
}
// errorString is a trivial implementation of error.
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}
因此io.EOF底層的類型是errors.errorString結(jié)構(gòu)體. 而結(jié)構(gòu)體類型是不支持定義常量的. 不過errors.errorString結(jié)構(gòu)體中只有一個字符串類型, io.EOF對應(yīng)的錯誤字符串正是"EOF".
我們可以為EOF重新實(shí)現(xiàn)一個以字符串為底層類型的新錯誤類型:
package io
type errorString string
func (e errorString) Error() string {
return string(e)
}
這個新的io.errorString實(shí)現(xiàn)了兩個特性: 首先是滿足了error接口; 其次它是基于string類型重新定義, 因此支持定義常量. 因此我們可以基于errorString重新將io.EOF定義為常量:
const EOF = errorString("EOF")
這樣EOF就變成了編譯時可以確定的常量類型, 常量的值依然是“EOF”字符串. 但是也帶來了新的問題: EOF已經(jīng)不再是一個接口類型, 它會破壞舊代碼的兼容性嗎?
關(guān)于“go語言eof錯誤指的是什么”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“go語言eof錯誤指的是什么”知識都有一定的了解,大家如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。