Go 2.0預計公布,在今天HackerNews引發(fā)眾多討論,眾多Bug即將填補,設計草案搶先預覽。
Go語言的開發(fā)者正著手準備開發(fā)2.0版本,并從以下三個方面發(fā)布了初步的設計方案(非官方正式版),以供社區(qū)開展討論:
泛型(generics)
錯誤處理(error handling)
錯誤值語義(error value semantics)
Go 2.0的總體目標是解決無法擴展到大型代碼庫以及無法滿足大型項目開發(fā)人員需求等問題。
泛型
改進目標
想必大多數(shù)用戶都對Go語言的泛型會表示無奈,很多網(wǎng)友甚至會說“根本就沒有泛型支持”。
Go 2.0的目標是通過允許帶有類型參數(shù)的參數(shù)多態(tài)(parametric polymorphism)來解決編寫Go庫的問題。
除了預期的容器類型之外,還希望能夠編寫有意義的庫來操作任意的map和channel值,并理想地編寫能夠同時操作[ ]byte和string值的多態(tài)函數(shù)。
Go的泛型必須明確記錄對類型參數(shù)的約束,作為調(diào)用者和實現(xiàn)之間明確的強制協(xié)議。當調(diào)用者不滿足這些約束或?qū)崿F(xiàn)超出限制時,編譯器需將錯誤清楚地報告出來。
Go中的多態(tài)性應該在編譯和運行時都可以實現(xiàn),這樣,有關實現(xiàn)策略的決策就可以留給編譯器來決定。這種靈活性將解決Go目前存在的一些難題。
草案設計
設計草案添加了一個新的語法,用于在類型或函數(shù)聲明中引入類型參數(shù)列表,例如:
1typeList(typeT)[]T23funcKeys(typeK,V)(mmap[K]V)[]K4
參數(shù)化聲明的使用,采用普通調(diào)用語法來提供類型參數(shù):
1varintsList(int)23keys:=Keys(int,string)(map[int]string{1:"one",2:"two"})
這些示例中的概括不需要T,K和V類型:任何類型都可以。 通常,實現(xiàn)可能需要約束可以使用的類型。例如,我們可能想要定義一個Set(T),以列表或映射的形式實現(xiàn),在這種情況下,類型T的值必須能夠進行相等的比較。為了表達這一點,設計草案引入了contract的概念。contract就像一個函數(shù)體,說明了類型必須支持的操作。例如,要聲明類型T的值必須是可比較的:
1contractEqual(tT){2t==t3}
錯誤處理
改進目標
Go 語言的錯誤處理是基于明確的目的而設計的。用戶應該從函數(shù)中返回所有可能的錯誤,并且檢查/處理這些返回值。和其他語言相比,這一點可能看起來有些繁瑣和不人性化。
Go 2希望錯誤檢查更加輕量級,減少用于錯誤檢查的Go程序文本的數(shù)量。
還希望使編寫錯誤處理變得更方便,從而提高程序員花時間處理錯誤的可能性。
且錯誤檢查和錯誤處理必須保持顯式,即在程序文本中可見。
草案設計
草案設計引入了兩種新的句法形式。
首先,它引入一個檢查表達式來檢查f(x, y, z)或檢查err,并標記一個顯式錯誤檢查。
其次,它引入了一個定義錯誤處理程序的handle語句。當錯誤檢查失敗時,它將控制轉(zhuǎn)移到最內(nèi)層處理程序,該處理程序?qū)⒖刂妻D(zhuǎn)移到它上面的下一個處理程序,以此類推,直到處理程序執(zhí)行返回語句為止。例如:
1funcCopyFile(src,dststring)error{ 2handleerr{ 3returnfmt.Errorf("copy%s%s:%v",src,dst,err) 4} 5 6r:=checkos.Open(src) 7deferr.Close() 8 9w:=checkos.Create(dst)10handleerr{11w.Close()12os.Remove(dst)//(onlyifacheckfails)13}1415checkio.Copy(w,r)16checkw.Close()17returnnil18}
在不返回錯誤的函數(shù)中允許check/handle組合。例如,一下是一個有用卻很簡單的程序功能:
1funcmain(){ 2hex,err:=ioutil.ReadAll(os.Stdin) 3iferr!=nil{ 4log.Fatal(err) 5} 6 7data,err:=parseHexdump(string(hex)) 8iferr!=nil{ 9log.Fatal(err)10}1112os.Stdout.Write(data)13}
這么寫會更簡單、清晰:
1funcmain(){2handleerr{3log.Fatal(err)4}56hex:=checkioutil.ReadAll(os.Stdin)7data:=checkparseHexdump(string(hex))8os.Stdout.Write(data)9}
錯誤值語義
改進目標
也許用戶對于Go的程序化的err有許多問題:這是一個RPCError嗎?這是net.OpError嗎?它適應net.Error的接口嗎?這是os.PathError嗎?
對于錯誤值,第一個問題,就是很難回答上述那些疑問。函數(shù)os.IsExist,os.IsNotExist,os.IsPermission和os.IsTimeout是主要問題。它們在通用性方面有兩個缺陷:每個函數(shù)僅測試一種特定類型的錯誤,第二,每個函數(shù)只能理解非常有限數(shù)量的包類型。
第二個問題看似沒什么,卻也很重要:深度嵌套錯誤(nested error)的報告太難以閱讀,并且沒有留給額外的細節(jié)空間,比如程序中的相關文件位置。
針對上述存在的兩個問題,Go 2首先希望能讓程序的錯誤檢查更容易,更不容易出錯,以提高實際程序的錯誤處理和魯棒性。其次,希望能夠以標準格式打印帶有附加細節(jié)的錯誤。
草案設計
這里有兩個主要問題:錯誤檢查和錯誤格式化,分別用兩個不同的方案解決。需要保持與現(xiàn)有代碼的互操作性,并允許包繼續(xù)定義自身的錯誤類型的約束,指向定義錯誤實現(xiàn)可以滿足的可選界面。
錯誤檢查(Error inspection)
對于錯誤檢查,設計草案遵循現(xiàn)有包(如github.com/pkg/errors)的規(guī)則,并為錯誤定義了一個可選接口,以返回錯誤包裝鏈中的下一個錯誤:
1packageerrors23typeWrapperinterface{4Unwrap()error5}
例如,上面假設的WriteError需要:
1func(e*WriteError)Unwrap()error{returne.Err}
利用這種方法,方案設計中添加了兩個新函數(shù)對錯誤打包:
1//Isreportswhethererroranyoftheerrorsinitschainisequaltotarget.2funcIs(err,targeterror)bool34//AscheckswhethererroranyoftheerrorsinitschainisavalueoftypeE.5//Ifso,itreturnsthediscoveredvalueoftypeE,withoksettotrue.6//Ifnot,itreturnsthezerovalueoftypeE,withoksettofalse.7funcAs(typeE)(errerror)(eE,okbool)8
錯誤格式(Error formatting)
對于錯誤格式,設計草案定義了根據(jù)錯誤來實現(xiàn)的可選接口:
1packageerrors23typeFormatterinterface{4Format(pPrinter)(nexterror)5}
-
編譯器
+關注
關注
1文章
1617瀏覽量
49019 -
go語言
+關注
關注
1文章
158瀏覽量
9016
原文標題:Go 2.0發(fā)布在即,程序員有太多話要說
文章出處:【微信號:AI_era,微信公眾號:新智元】歡迎添加關注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論