国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Go 語言一次真實的錯誤吞并的教訓

開發 后端
在幾天前寫的代碼中,犯了幾個比較典型的錯誤,帶來不小的麻煩。特在此復現一下,吸取教訓。

在幾天前寫的代碼中,犯了幾個比較典型的錯誤,帶來不小的麻煩。特在此復現一下,吸取教訓。

[[332662]]

情景描述

代碼中需要實現一個客戶端與服務器的數據重傳機制,通過write寫數據給服務器,read讀取服務器返回。一旦中途發生錯誤,每隔1s就嘗試重新寫讀數據。當超過上下文時間,重傳失敗。重傳實現代碼retry如下。

  1. func retry(ctx context.Context) (data string, err error) { 
  2.  
  3. LOOP: 
  4.  for i:=1;;i++{ 
  5.   err = write() 
  6.   if err == nil{ 
  7.    res, err := read() 
  8.    if err == nil{ 
  9.     data = string(res) 
  10.     return data, err 
  11.    } 
  12.   } 
  13.  
  14.   log.Printf("change data failed, err: %v, retry times : %d\n", err, i) 
  15.  
  16.   select { 
  17.   case <-ctx.Done(): 
  18.    log.Printf("retry failed"
  19.    break LOOP 
  20.   case <-time.After(1 * time.Second): 
  21.   } 
  22.  } 
  23.  return "", err 

讀寫服務器數據函數和調用重傳代碼mock如下。

  1. func write() error { 
  2.  return nil 
  3.  
  4. func read() ([]byte, error) { 
  5.  return []byte("hello world"), errors.New("this is a error"
  6.  
  7. func main() { 
  8.  ctx,_ := context.WithTimeout(context.Background(),5*time.Second
  9.  _, _ = retry(ctx) 
  10.  time.Sleep(10*time.Second

write返回err為nil,read有非nil返回。這種情況下,日志輸出如下。

  1. 2020/07/05 09:30:57 change data failed, err: <nil>, retry times : 1 
  2. 2020/07/05 09:30:58 change data failed, err: <nil>, retry times : 2 
  3. 2020/07/05 09:30:59 change data failed, err: <nil>, retry times : 3 
  4. 2020/07/05 09:31:00 change data failed, err: <nil>, retry times : 4 
  5. 2020/07/05 09:31:01 change data failed, err: <nil>, retry times : 5 
  6. 2020/07/05 09:31:02 retry failed 

原因分析

可以看到的是,如預想的一樣:當發生錯誤時,就重新嘗試write和read。即重傳機制生效。但是,日志中為何err會為nil,read方法的錯誤返回被吞掉了?

經過排查,發現原因就在于——Go語法糖:=(短變量聲明)的不當使用。

  1. err = write() 
  2.  if err == nil{ 
  3.   res, err := read() 
  4.   if err == nil{ 
  5.    data = string(res) 
  6.    return data, err 
  7.   } 
  8.  } 
  9.  
  10.  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內容被吞。

因此,為了避免此類錯誤發生,相應代碼調整如下。

  1. var res []byte 
  2.  res, err = read() 
  3.  if err == nil{ 
  4.   data = string(res) 
  5.   return data, err 
  6.  } 

此時,當read返回err非nil時,日志打印如下。

  1. 2020/07/05 09:46:16 change data failed, err: this is a error, retry times : 1 
  2. 2020/07/05 09:46:17 change data failed, err: this is a error, retry times : 2 
  3. 2020/07/05 09:46:18 change data failed, err: this is a error, retry times : 3 
  4. 2020/07/05 09:46:19 change data failed, err: this is a error, retry times : 4 
  5. 2020/07/05 09:46:20 change data failed, err: this is a error, retry times : 5 
  6. 2020/07/05 09:46:21 retry failed 

總結

一、Go語法糖——短變量聲明(:=)使用注意事項。

  • :=表示聲明+賦值。
  •  短變量聲明不需要聲明所有在左邊的變量。如果一些變量在同一個詞法塊中聲明,那么對于這些變量,短聲明的行為等同于賦值(同時更改了這些變量的作用域)。

二、異常判斷規則

在上述場景代碼中,是一個多層級條件判斷的情形,其判斷規則是err為nil。但這是一種不恰當的處理邏輯。合理的判斷條件,是對異常情況作判斷,而將正常邏輯置于條件之外。那么,修改后的retry條件判斷邏輯應該如下所示。

  1. func retry(ctx context.Context) (data string, err error) { 
  2.  
  3. LOOP: 
  4.  for i:=1;;i++{ 
  5.   err = write() 
  6.   if err != nil{ 
  7.    log.Printf("write data failed, err: %v, retry times : %d\n", err, i) 
  8.    select { 
  9.    case <-ctx.Done(): 
  10.     log.Printf("retry failed"
  11.     break LOOP 
  12.    case <-time.After(1 * time.Second): 
  13.    } 
  14.    continue 
  15.   } 
  16.  
  17.   res, err := read() 
  18.   if err != nil{ 
  19.    log.Printf("read data failed, err: %v, retry times : %d\n", err, i) 
  20.    select { 
  21.    case <-ctx.Done(): 
  22.     log.Printf("retry failed"
  23.     break LOOP 
  24.    case <-time.After(1 * time.Second): 
  25.    } 
  26.    continue 
  27.   } 
  28.  
  29.   data = string(res) 
  30.   return data, err 
  31.  
  32.  } 
  33.  return "", err 

這樣,正常的處理流程,其主邏輯均在最外層,只有異常情況(err!=nil)才進入異常處理邏輯。當采用這種判斷規則之后,就不存在多層條件嵌套語句,由語法糖帶來的問題,也不復存在。

責任編輯:未麗燕 來源: Go語言中文網
相關推薦

2021-12-20 10:15:16

zip密碼命令網絡安全

2015-04-28 15:31:09

2023-09-11 00:14:46

后端團隊項目

2011-06-28 10:41:50

DBA

2021-12-28 06:55:09

事故訂單號績效

2021-04-29 09:02:44

語言Go 處理

2014-11-17 10:05:12

Go語言

2022-12-09 08:52:51

Go匿名接口

2015-08-17 14:50:19

亞馬遜云平臺應用遷移

2021-12-27 10:08:16

Python編程語言

2020-10-24 13:50:59

Python編程語言

2024-01-04 07:49:00

Go語言方法

2022-03-02 09:01:07

CPU使用率優化

2022-10-17 00:07:55

Go語言標準庫

2011-04-07 11:20:21

SQLServer

2012-08-28 09:21:59

Ajax查錯經歷Web

2021-11-01 17:29:02

Windows系統Fork

2009-07-23 08:40:37

VMware遷移備份歸檔

2020-01-14 11:17:33

Go并發Linux

2024-04-17 08:42:15

Go語言分布式鎖
點贊
收藏

51CTO技術棧公眾號

欧美色手机在线观看| 美女久久久久久久久久久| 久草这里只有精品视频| 精品久久久久人成 | 亚洲v日韩v欧美v综合| 国产999精品视频| 干日本少妇首页| 欧美成人a交片免费看| h片在线免费观看| 午夜在线一区| 亚洲第一综合天堂另类专| 天堂√在线观看一区二区| 男人av在线播放| 久久se精品一区精品二区| 国产精品日韩一区二区| 免费在线看黄色| 麻豆国产欧美一区二区三区| 亚洲图片欧洲图片av| 91专区在线观看| 女仆av观看一区| 亚洲第一综合色| 国产精品露出视频| 亚洲a一区二区三区| 欧美一级国产精品| 成人免费网站在线观看| 日本美女在线中文版| 日韩国产精品久久| 日韩视频免费看| 国产精品久久久久久精| 国产精品久久久亚洲一区| 亚洲视频国产视频| 男女视频网站免费观看| 午夜精品亚洲| 国产亚洲精品美女| 精品成人av| 亚洲一区免费视频| 日韩久久久久久久| 亚洲国产欧美在线观看| 欧美偷拍一区二区| 精品欧美一区免费观看α√| 日韩午夜电影网| 精品女同一区二区| 国产视频1区2区3区| 国产一级久久| 亚洲人体一区| 国产一区二区三区站长工具| 日韩精品久久久久| 美女的尿口免费视频| 香港成人在线视频| 男人天堂网站在线| 欧美日韩一区二区综合| 国产视频欧美视频| 羞羞网www| 成人av先锋影音| 97netav| 丝袜美腿一区| 欧美激情国产高清| h片在线观看| 亚洲影视在线观看| 韩国福利在线| 国产欧美精品一区二区三区四区| 国产精品白丝jk白祙| 日本亚洲欧洲无免费码在线| 欧美日韩一区国产| 网友自拍亚洲| 国产精品久久久久av| 黄瓜视频成人app免费| 91成人看片片| xxxxx国产| 99久久久国产精品免费蜜臀| 色一区av在线| a级毛片免费观看在线| 国产一区二区av| 欧美hd在线| 日产精品99久久久久久| 性色av一区二区怡红| 国产熟女高潮视频| 国产麻豆成人精品| 久久免费一区| 欧美精品九九| 国产在线观看不卡| 亚洲v天堂v手机在线| 久久精品国产综合| 成人直播视频| 欧美三级资源在线| 在线不卡一区| 在线观看日韩av| 草草在线观看| 欧美亚洲综合网| 992tv国产精品成人影院| 精品盗摄一区二区三区| 久久电影中文字幕| 久久精品青青大伊人av| 99香蕉国产精品偷在线观看| 亚洲一区二区三区在线视频| 日韩aaaa| 你懂的av在线| 精品久久久久久久一区二区蜜臀| 国产欧美一区二区三区精品观看 | 欧美三级一级片| 日韩一级片网址| 午夜久久免费观看| 黄色国产小视频| 国产亚洲美州欧州综合国| 男女超爽视频免费播放| 91精品久久久久久久91蜜桃| 黄色网在线播放| 欧美岛国在线观看| 欧美韩日亚洲| 精品日韩一区二区| 91成人观看| 天堂资源在线观看| 国产精品午夜春色av| 天堂在线亚洲| 精品国产乱码久久久久久虫虫漫画 | 992tv成人免费视频| 粉嫩精品导航导航| 国内外成人免费激情在线视频| 日韩欧美高清一区二区三区| 久久久久亚洲精品国产| 国产suv精品一区二区三区| 国产不卡一区二区视频| 91在线视频在线| 老司机2019福利精品视频导航| 激情小说网站亚洲综合网 | 日韩av电影在线免费播放| 国产欧美日韩卡一| 看亚洲a级一级毛片| 久久久噜久噜久久综合| 国产美女精品在线| 超碰在线99| 一区二区三区日韩视频| 久久综合久久综合亚洲| а√最新版地址在线天堂| 色8久久人人97超碰香蕉987| 欧美人与禽猛交乱配| 久久伊人资源站| 国产成人免费视频| 91黑丝在线| 日韩女在线观看| 亚洲中国最大av网站| 成人欧美一区| 亚洲天天做日日做天天谢日日欢 | 影院欧美亚洲| 国产精品裸体一区二区三区| 337p亚洲精品色噜噜| 黑人狂躁日本妞一区二区三区| www.欧美日本| 欧美第一黄色网| 亚洲国产成人一区二区三区| swag国产精品一区二区| 亚洲va欧美va国产综合剧情| 黑人狂躁日本妞一区二区三区| 中文无码久久精品| 久久观看最新视频| 亚洲午夜影视影院在线观看| 精品一区不卡| 国产毛片av在线| 在线成人免费网站| 91麻豆免费看| 毛片在线播放网站| 亚洲性生活视频| 99视频在线精品| 国内成人自拍| 1pondo在线播放免费| 欧美精品在线视频观看| 色天下一区二区三区| 久久另类ts人妖一区二区| 精品免费日韩av| 成人精品鲁一区一区二区| 久久365资源| 色涩成人影视在线播放| 国产视频在线一区二区| 国产亚洲一区二区在线观看| 青青一区二区三区| 成人午夜视频在线观看免费| 精品中文字幕在线2019| 黑人欧美xxxx| 久久99热这里只有精品| 97品白浆高清久久久久久| 午夜亚洲成人| 另类天堂视频在线观看| 国产美女精品| 91精品美女| 在线视频专区| 中国一区二区三区| 在线观看欧美日本| 国产在线国偷精品产拍免费yy| 青青久草在线| 性欧美亚洲xxxx乳在线观看| 欧美色综合一区二区三区| 日本中文字幕网址| 日本一区二区三区免费观看| 亚洲电影在线| 国产 日韩 欧美一区| 又黄又www| 一本久道高清无码视频| 精品成人一区二区| 亚洲国产精品成人综合| 久久精品成人|