您好,登錄后才能下訂單哦!
這篇文章主要講解了“怎么解決Go語言的read讀取錯誤”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么解決Go語言的read讀取錯誤”吧!
情景描述
代碼中需要實現一個客戶端與服務器的數據重傳機制,通過write寫數據給服務器,read讀取服務器返回。一旦中途發生錯誤,每隔1s就嘗試重新寫讀數據。當超過上下文時間,重傳失敗。重傳實現代碼retry如下。
func retry(ctx context.Context) (data string, err error) { LOOP: for i:=1;;i++{ err = write() if err == nil{ res, err := read() if err == nil{ data = string(res) return data, err } } log.Printf("change data failed, err: %v, retry times : %d\n", err, i) select { case <-ctx.Done(): log.Printf("retry failed") break LOOP case <-time.After(1 * time.Second): } } return "", err }
讀寫服務器數據函數和調用重傳代碼mock如下。
func write() error { return nil } func read() ([]byte, error) { return []byte("hello world"), errors.New("this is a error") } func main() { ctx,_ := context.WithTimeout(context.Background(),5*time.Second) _, _ = retry(ctx) time.Sleep(10*time.Second) }
write返回err為nil,read有非nil返回。這種情況下,日志輸出如下。
2020/07/05 09:30:57 change data failed, err: <nil>, retry times : 1 2020/07/05 09:30:58 change data failed, err: <nil>, retry times : 2 2020/07/05 09:30:59 change data failed, err: <nil>, retry times : 3 2020/07/05 09:31:00 change data failed, err: <nil>, retry times : 4 2020/07/05 09:31:01 change data failed, err: <nil>, retry times : 5 2020/07/05 09:31:02 retry failed
原因分析
可以看到的是,如預想的一樣:當發生錯誤時,就重新嘗試write和read。即重傳機制生效。但是,日志中為何err會為nil,read方法的錯誤返回被吞掉了?
經過排查,發現原因就在于——Go語法糖:=(短變量聲明)的不當使用。
err = write() if err == nil{ res, err := read() if err == nil{ data = string(res) return data, err } } log.Printf("change data failed, err: %v, retry times : %d\n", err, i)
在retry中,err是已被聲明的變量類型error。由于read返回的是兩個變量,故小菜刀在此利用短變量聲明res變量,接受read的第一個返回參數。但是,此舉會改變err的作用范圍:err成為了一個局部變量。什么意思呢?即此時的err被短變量聲明所作用,成為了新聲明對象,它只能作用于內部區域了。對于外部log.Printf而言,其引用到的err還是write方法生成的err對象。因此,即使read方法返回的err不為空,log.Printf打印的還是write方法的err結果,導致read的err內容被吞。
因此,為了避免此類錯誤發生,相應代碼調整如下。
var res []byte res, err = read() if err == nil{ data = string(res) return data, err }
此時,當read返回err非nil時,日志打印如下。
2020/07/05 09:46:16 change data failed, err: this is a error, retry times : 1 2020/07/05 09:46:17 change data failed, err: this is a error, retry times : 2 2020/07/05 09:46:18 change data failed, err: this is a error, retry times : 3 2020/07/05 09:46:19 change data failed, err: this is a error, retry times : 4 2020/07/05 09:46:20 change data failed, err: this is a error, retry times : 5 2020/07/05 09:46:21 retry failed
感謝各位的閱讀,以上就是“怎么解決Go語言的read讀取錯誤”的內容了,經過本文的學習后,相信大家對怎么解決Go語言的read讀取錯誤這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。