真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

go語(yǔ)言除法 golang除法

深入剖析:一套在 Go 中傳遞、返回、暴露錯(cuò)誤,便于回查的解決方案

作者:andruzhang,騰訊 IEG 后臺(tái)開(kāi)發(fā)工程師

10余年的雙橋網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都營(yíng)銷網(wǎng)站建設(shè)的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整雙橋建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)公司從事“雙橋網(wǎng)站設(shè)計(jì)”,“雙橋網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

在后臺(tái)開(kāi)發(fā)中,針對(duì)錯(cuò)誤處理,有三個(gè)維度的問(wèn)題需要解決:

一個(gè)面向過(guò)程的函數(shù),在不同的處理過(guò)程中需要 handle 不同的錯(cuò)誤信息;一個(gè)面向?qū)ο蟮暮瘮?shù),針對(duì)一個(gè)操作所返回的不同類型的錯(cuò)誤,有可能需要進(jìn)行不同的處理。此外,在遇到錯(cuò)誤時(shí),也可以使用斷言的方式,快速中止函數(shù)流程,大大提高代碼的可讀性。

在許多高級(jí)語(yǔ)言中都提供了 try ... catch 的語(yǔ)法,函數(shù)內(nèi)部可以通過(guò)這種方案,實(shí)現(xiàn)一個(gè)統(tǒng)一的錯(cuò)誤處理邏輯。而即便是 C 這種 “中級(jí)語(yǔ)言” 雖然沒(méi)有,但是程序員也可以使用宏定義的方式,來(lái)實(shí)現(xiàn)某種程度上的錯(cuò)誤斷言。

但是,對(duì)于 Go 的情況就比較尷尬了。

我們先來(lái)看斷言,我們的目的是,僅使用一行代碼就能夠檢查錯(cuò)誤并終止當(dāng)前函數(shù)。由于沒(méi)有 throw,沒(méi)有宏,如果要實(shí)現(xiàn)一行斷言,有兩種方法。

第一種是把 if 的錯(cuò)誤判斷寫在一行內(nèi),比如:

第二種方法是借用 panic 函數(shù),結(jié)合 recover 來(lái)實(shí)現(xiàn):

這兩種方法都值得商榷。

首先,將 if 寫在同一行內(nèi)的問(wèn)題有:

至于第二種方法,我們要分情況看;

不過(guò)使用 panic 來(lái)斷言的方案,雖然在業(yè)務(wù)邏輯中基本上不用,但在測(cè)試場(chǎng)景下則是非常常見(jiàn)的。測(cè)試嘛,用牛刀有何不可?稍微大一點(diǎn)的系統(tǒng)開(kāi)銷也沒(méi)啥問(wèn)題。對(duì)于 Go 來(lái)說(shuō),非常熱門的單元測(cè)試框架 goconvey 就是使用 panic 機(jī)制來(lái)實(shí)現(xiàn)單元測(cè)試中的斷言,用的人都說(shuō)好。

綜上,在 Go 中,對(duì)于業(yè)務(wù)代碼,筆者不建議采用斷言,遇到錯(cuò)誤的時(shí)候建議還是老老實(shí)實(shí)采用這種格式:

而在單測(cè)代碼中,則完全可以大大方方地采用類似于 goconvey 之類基于 panic 機(jī)制的斷言。

眾所周知 Go 是沒(méi)有 try ... catch 的,而且從官方的態(tài)度來(lái)看,短時(shí)間內(nèi)也沒(méi)有考慮的計(jì)劃。但程序員有這個(gè)需求呀。筆者采用的方法,是將需要返回的 err 變量在函數(shù)內(nèi)部全局化,然后結(jié)合 defer 統(tǒng)一處理:

這種方案要特別注意變量作用域問(wèn)題.比如前面的 if err = DoSomething(); err != nil { 行,如果我們將 err = ... 改為 err := ...,那么這一行中的 err 變量和函數(shù)最前面定義的 (err error) 不是同一個(gè)變量,因此即便在此處發(fā)生了錯(cuò)誤,但是在 defer 函數(shù)中無(wú)法捕獲到 err 變量了。

在 try ... catch 方面,筆者其實(shí)沒(méi)有特別好的方法來(lái)模擬,即便是上面的方法也有一個(gè)很讓人頭疼的問(wèn)題:defer 寫法導(dǎo)致錯(cuò)誤處理前置,而正常邏輯后置了,從可讀性的角度來(lái)說(shuō)非常不友好。因此也希望讀者能夠指教。同時(shí)還是希望 Go 官方能夠繼續(xù)迭代,支持這種語(yǔ)法。

這一點(diǎn)在 Go 里面,一開(kāi)始看起來(lái)還是比較統(tǒng)一的,這就是 Go 最開(kāi)始就定義的 error 類型,以系統(tǒng)標(biāo)準(zhǔn)的方式,統(tǒng)一了進(jìn)程內(nèi)函數(shù)級(jí)的錯(cuò)誤返回模式。調(diào)用方使用 if err != nil 的統(tǒng)一模式,來(lái)判斷一個(gè)調(diào)用是不是成功了。

但是隨著 Go 的逐步推廣,由于 error 接口的高自由度,程序員們對(duì)于 “如何判斷該錯(cuò)誤是什么錯(cuò)誤” 的時(shí)候,出現(xiàn)了分歧。

在 Go 1.13 之前,對(duì)于 error 類型的傳遞,有三種常見(jiàn)的模式:

這個(gè)流派很簡(jiǎn)單,就是將各種錯(cuò)誤信息直接定義為一個(gè)類枚舉值的模式,比如:

當(dāng)遇到相應(yīng)的錯(cuò)誤信息時(shí),直接返回對(duì)應(yīng)的 error 類枚舉值就行了。對(duì)于調(diào)用方也非常方便,可以采用 switch - case 來(lái)判斷錯(cuò)誤類型:

個(gè)人覺(jué)得這種設(shè)計(jì)模式本質(zhì)上還是 C error code 模式。

這種流派則是充分使用了 “error 是一個(gè) interface” 的特性,重新自定義一個(gè) error 類型。一方面是用不同的類型來(lái)表示不同的錯(cuò)誤分類,另一方面則能夠?qū)崿F(xiàn)對(duì)于同一錯(cuò)誤類型,能夠給調(diào)用方提供更佳詳盡的信息。舉個(gè)例子,我們可以定義多個(gè)不同的錯(cuò)誤類型如下:

對(duì)于調(diào)用方,則通過(guò)以下代碼來(lái)判斷不同的錯(cuò)誤:

這種模式,一方面可以透?jìng)鞯讓渝e(cuò)誤,另一方面又可以添加自定義的信息。但對(duì)于調(diào)用方而言,災(zāi)難在于如果要判斷某一個(gè)錯(cuò)誤的具體類型,只能用 strings.Contains() 來(lái)實(shí)現(xiàn),而錯(cuò)誤的具體描述文字是不可靠的,同一類型的信息可能會(huì)有不同的表達(dá);而在 fmt.Errorf 的過(guò)程中,各個(gè)業(yè)務(wù)添加的額外信息也可能會(huì)有不同的文字,這帶來(lái)了極大的不可靠性,提高了模塊之間的耦合度。

在 go 1.13 版本發(fā)布之后,針對(duì) fmt.Errorf 增加了 wraping 功能,并在 errors 包中添加了 Is() 和 As() 函數(shù)。關(guān)于這個(gè)模式的原理和使用已經(jīng)有很多文章了,本文就不再贅述。

這個(gè)功能,合并并改造了前文的所謂 “== 流派” 和 “fmt.Errorf” 流派,統(tǒng)一使用 errors.Is() 函數(shù);此外,也算是官方對(duì)類型斷言流派的認(rèn)可(專門用 As() 函數(shù)來(lái)支持)。

在實(shí)際應(yīng)用中,函數(shù)/模塊透?jìng)麇e(cuò)誤時(shí),應(yīng)該采用 Go 的 error wrapping 模式,也就是 fmt.Errorf() 配合 %w 使用,業(yè)務(wù)方可以放心地添加自己的錯(cuò)誤信息,只要調(diào)用方統(tǒng)一采用 errors.Is() 和 errors.As() 即可。

服務(wù)/系統(tǒng)層面的錯(cuò)誤信息返回,大部分協(xié)議都可以看成是 code - message 模式或者是其變體:

這種模式的特點(diǎn)是:code 是給程序代碼使用的,代碼判斷這是一個(gè)什么類型的錯(cuò)誤,進(jìn)入相應(yīng)的分支處理;而 message 是給人看的,程序可以以某種形式拋出或者記錄這個(gè)錯(cuò)誤信息,供用戶查看。

在這一層面有什么問(wèn)題呢?code for computer,message for user,好像挺好的。

但有時(shí)候,我們可能會(huì)收到用戶/客戶反饋一個(gè)問(wèn)題:“XXX 報(bào)錯(cuò)了,幫忙看看什么問(wèn)題?”。用戶看不懂我們的錯(cuò)誤提示嗎?

在筆者的經(jīng)驗(yàn)中,我們?cè)谑褂?code - message 機(jī)制的時(shí)候,特別是業(yè)務(wù)初期,難以避免的是前后端的設(shè)計(jì)文案沒(méi)能完整地覆蓋所有的錯(cuò)誤用例,或者是錯(cuò)誤極其罕見(jiàn)。因此當(dāng)出現(xiàn)錯(cuò)誤時(shí),提示曖昧不清(甚至是直接提示錯(cuò)誤信息),導(dǎo)致用戶從錯(cuò)誤信息中找到解決方案

在這種情況下,盡量覆蓋所有錯(cuò)誤路徑肯定是最完美的方法。不過(guò)在做到這一點(diǎn)之前,碼農(nóng)們往往有下面的解決方案:

既要隱藏信息,又要暴露信息,我可以摔盤子嗎……

這里,筆者從日益普及的短信驗(yàn)證碼有了個(gè)靈感——人的短期記憶對(duì) 4 個(gè)字符還是比較強(qiáng)的,因此我們可以考慮把錯(cuò)誤代碼縮短到 4 個(gè)字符——不區(qū)分大小寫,因?yàn)槿绻嗽谟洃洉r(shí)還要記錄大小寫的話,難度會(huì)增加不少。

怎么用 4 個(gè)字符表示盡量多的數(shù)據(jù)呢?數(shù)字+字母總共有 36 個(gè)字符,理論上使用 4 位 36 進(jìn)制可以表示 36x36x36x36 = 1679616 個(gè)值。因此我們只要找到一個(gè)針對(duì)錯(cuò)誤信息字符串的哈希算法,把輸出值限制在 1679616 范圍內(nèi)就行了。

這里我采用的是 MD5 作為例子。MD5 的輸出是 128 位,理論上我可以取 MD5 的輸出,模 1679616 就可以得到一個(gè)簡(jiǎn)易的結(jié)果。實(shí)際上為了減少除法運(yùn)算,我采用的是取高 20 位(0xFFFFF)的簡(jiǎn)易方式(20 位二進(jìn)制的最大值為 1048575),然后將這個(gè)數(shù)字轉(zhuǎn)成 36 進(jìn)制的字符串輸出。

當(dāng)出現(xiàn)異常錯(cuò)誤時(shí),我們可以將 message 的提示信息如下展示:“未知錯(cuò)誤,錯(cuò)誤代碼 30EV,如需協(xié)助,請(qǐng)聯(lián)系 XXX”。順帶一提,30EV 是 "Access denied for user 'db_user'@'127.0.0.1'" 的計(jì)算結(jié)果,這樣一來(lái),我就對(duì)調(diào)用方隱藏了敏感信息。

至于后臺(tái)側(cè),還是需要實(shí)實(shí)在在地將這個(gè)哈希值和具體的錯(cuò)誤信息記錄在日志或者其他支持搜索的渠道里。當(dāng)用戶提供該代碼時(shí),可以快速定位。

這種方案的優(yōu)點(diǎn)很明顯:

簡(jiǎn)易的錯(cuò)誤碼生成代碼如下:

當(dāng)然這種方案也有局限性,筆者能想到的是需要注意以下兩點(diǎn):

此外,筆者需要再?gòu)?qiáng)調(diào)的是:在開(kāi)發(fā)中,針對(duì)各種不同的、正式的錯(cuò)誤用例依然需要完整覆蓋,盡可能通過(guò)已有的 code - message 機(jī)制將足夠清晰的信息告知主調(diào)方。這種 hashcode 的錯(cuò)誤代碼生成方法,僅適用于錯(cuò)誤用例遺漏、或者是快速迭代過(guò)程中,用于發(fā)現(xiàn)和調(diào)試遺漏的錯(cuò)誤用例的臨時(shí)方案。

golang是什么意思

Go語(yǔ)言(又稱 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 開(kāi)發(fā)的一種靜態(tài)強(qiáng)類型、編譯型語(yǔ)言。Go 語(yǔ)言語(yǔ)法與 C 相近,但功能上有:內(nèi)存安全,GC(垃圾回收),結(jié)構(gòu)形態(tài)及 CSP-style 并發(fā)計(jì)算。 擴(kuò)展資料

Go語(yǔ)言主要用作服務(wù)器端開(kāi)發(fā),其定位是用來(lái)開(kāi)發(fā)“大型軟件”的,適合于很多程序員一起開(kāi)發(fā)大型軟件,并且開(kāi)發(fā)周期長(zhǎng),支持云計(jì)算的網(wǎng)絡(luò)服務(wù)。Go語(yǔ)言能夠讓程序員快速開(kāi)發(fā),并且在軟件不斷的'增長(zhǎng)過(guò)程中,它能讓程序員更容易地進(jìn)行維護(hù)和修改。它融合了傳統(tǒng)編譯型語(yǔ)言的高效性和腳本語(yǔ)言的易用性和富于表達(dá)性。

Go語(yǔ)言作為服務(wù)器編程語(yǔ)言,很適合處理日志、數(shù)據(jù)打包、虛擬機(jī)處理、文件系統(tǒng)、分布式系統(tǒng)、數(shù)據(jù)庫(kù)代理等;網(wǎng)絡(luò)編程方面,Go語(yǔ)言廣泛應(yīng)用于Web應(yīng)用、API應(yīng)用、下載應(yīng)用等;除此之外,Go語(yǔ)言還可用于內(nèi)存數(shù)據(jù)庫(kù)和云平臺(tái)領(lǐng)域,目前國(guó)外很多云平臺(tái)都是采用Go開(kāi)發(fā)。

用go語(yǔ)言寫一個(gè)簡(jiǎn)單的加減乘除的代碼,急求 在線等

/*Note:YourchoiceisCIDE*/#include"stdio.h"#include"stdlib.h"#include"ctype.h"intn=0;charrecord[20];floatproduct();floatchange();floatmuli(){floatsumm;summ=product();while(record[n]=='-'||record[n]=='+'){switch(record[n]){case'+':n++;summ+=product();break;case'-':n++;summ-=product();break;}}returnsumm;}floatproduct(){floatsump;sump=change();while(record[n]=='*'||record[n]=='/'){switch(record[n]){case'*':n++;sump*=change();break;case'/':n++;sump/=change();break;}}returnsump;}floatchange(){floatsumc;charrec[20],i=0;if(record[n]=='('){n++;sumc=muli();}if(record[n]==')')n++;while(isdigit(record[n])||record[n]=='.'){while(isdigit(record[n])||record[n]=='.')rec[i++]=record[n++];rec[i]='\0';sumc=atof(rec);}returnsumc;}voidmain(){while(1){n=0;scanf("%s",record);printf("%s=%g\n",record,muli());}}這個(gè)是比較簡(jiǎn)單的。。。但是有點(diǎn)難理解。。。不過(guò)運(yùn)行絕對(duì)正確。。還支持括號(hào)。。。但是在這個(gè)程序里面我加沒(méi)有出錯(cuò)處理。。。另一種方法是用棧寫。。。這個(gè)好理解。。但是麻煩。。。

golang異常處理

go語(yǔ)言沒(méi)有使用像java python等語(yǔ)言的try catch/except 語(yǔ)句來(lái)處理異常,而是使用它特有的panic,recover,defer來(lái)捕獲和處理異常

分析:

divide是一個(gè)做除法的函數(shù),可能會(huì)出現(xiàn)除數(shù)為0的錯(cuò)誤,所以在函數(shù)一開(kāi)頭就定義了一個(gè)defer匿名函數(shù)(注意這里的匿名函數(shù)定義完后面要帶上括號(hào)才能執(zhí)行),這個(gè)匿名函數(shù)被defer修飾了所以只在divide函數(shù)執(zhí)行完才會(huì)執(zhí)行,而不是一進(jìn)來(lái)就執(zhí)行。后面判斷b是否等于0,如果為零的話我們手動(dòng)使用panic拋出了異常,這個(gè)異常是在divide函數(shù)退出前執(zhí)行的defer匿名函數(shù)里通過(guò)recover()來(lái)捕獲的,如果err不為空就說(shuō)明發(fā)生了錯(cuò)誤,打印error happen!和panic拋出的divided by zero!! 然后主協(xié)程返回到主函數(shù)main里,繼續(xù)執(zhí)行后面的打印


網(wǎng)頁(yè)標(biāo)題:go語(yǔ)言除法 golang除法
轉(zhuǎn)載來(lái)源:http://weahome.cn/article/dogddde.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部