Go開發(fā)關(guān)鍵技術(shù)指南:Go2 Transition

Go2 Transition

Go2的設(shè)計草案在Go 2 Draft Designs或者這里暂幼,而Go1如何遷移到Go2也是我個人特別關(guān)心的問題俐载,Python2和Python3的那種不兼容的遷移方式簡直就是噩夢一樣的記憶盟广。Go的提案中欺劳,有一個專門說了遷移的問題厌均,參考Go2 Transition梅肤。

Go2 Transition還不是最終方案身坐,不過它也對比了各種語言的遷移,還是很有意思的一個總結(jié)蛋叼。這個提案描述了在非兼容性變更時焊傅,如何給開發(fā)者挖的坑最小剂陡。

目前Go1的標(biāo)準(zhǔn)庫是遵守兼容性原則的,參考Go 1 compatibility guarantee狐胎,這個規(guī)范保證了Go1沒有兼容性問題鸭栖,幾乎可以沒有影響的升級比如從Go1.2升級到Go1.11。幾乎的意思握巢,是很大概率是沒有問題晕鹊,當(dāng)然如果用了一些非常冷門的特性,可能會有坑暴浦,我們遇到過json解析時溅话,內(nèi)嵌結(jié)構(gòu)體的數(shù)據(jù)成員也得是exposed的才行,而這個在老版本中是可以非exposed歌焦;還遇到過cgo對于鏈接參數(shù)的變更導(dǎo)致編譯失敗飞几,這些問題幾乎很難遇到,都可以算是兼容的吧独撇,有時候只是把模糊不清的定義清楚了而已屑墨。

Go2在語言和標(biāo)準(zhǔn)庫上,會打破Go1的兼容性規(guī)范纷铣,也就是和Go1不再兼容绪钥。不過Go是分布式開源社區(qū)在維護(hù),不能依賴于flag day关炼,還是要容許不同Go版本寫的package的互操作性程腹。先了解下各個語言如何考慮兼容性:

  • C是嚴(yán)格向后兼容的,很早寫的程序總是能在新的編譯器中編譯儒拂。另外新的編譯器也支持指定之前的標(biāo)準(zhǔn)寸潦,比如-std=c90使用ISO C90標(biāo)準(zhǔn)編譯程序。關(guān)鍵的特性是編譯成目標(biāo)文件后社痛,不同版本的C的目標(biāo)文件见转,能完美的鏈接成執(zhí)行程序。C90實際上是對之前K&R C版本不兼容的蒜哀,主要引入了volatile關(guān)鍵字斩箫,還有整數(shù)精度問題,還引入了trigraphs撵儿,最糟糕的是引入了undefined行為比如數(shù)組越界和整數(shù)溢出的行為未定義乘客。從C上可以學(xué)到的是:后向兼容非常重要;非常小的打破兼容性也問題不大特別是可以通過編譯器選項來處理淀歇;能將不同版本的目標(biāo)文件鏈接到一起是非常關(guān)鍵的易核;undefined行為嚴(yán)重困擾開發(fā)者容易造成問題。
  • C++也是ISO組織驅(qū)動的語言浪默,和C一樣也是向后兼容的牡直。C++和C一樣坑爹的地方坑到吐血缀匕,比如undefined行為等等。盡管一直保持向后兼容碰逸,但是新的C++代碼比如C++11看起來完全不同乡小,這是因為有新的改變的特性,比如很少會用裸指針饵史,比如range代替了傳統(tǒng)的for循環(huán)劲件,這導(dǎo)致熟悉老C++語法的程序員看新的代碼非常難受甚至看不懂。C++毋庸置疑是非常流行的约急,但是新的語言標(biāo)準(zhǔn)在這方面沒有貢獻(xiàn)。從C++上可以學(xué)到的新東西是:盡管保持向后兼容苗分,語言的新版本可能也會帶來巨大的不同的感受(保持向后兼容并不能保證能持續(xù)看懂)厌蔽。
  • Java也是向后兼容的,是在字節(jié)碼層面和語言層面都向后兼容摔癣,盡管語言上不斷的新增了關(guān)鍵字奴饮。Java的標(biāo)準(zhǔn)庫非常龐大,也不斷的在更新择浊,過時的特性會被標(biāo)記為deprecated并且編譯時會有警告戴卜,理論上一定版本后deprecated的特性會不可用。Java的兼容性問題主要在JVM解決琢岩,如果用新的版本編譯的字節(jié)碼投剥,得用新的JVM才能執(zhí)行。Java還做了一些前向兼容担孔,這個影響了字節(jié)碼啥的(我本身不懂Java江锨,作者也不說自己不是專家,我就沒仔細(xì)看了)糕篇。Java上可以學(xué)到的新東西是:要警惕因為保持兼容性而限制語言未來的改變啄育。
  • Python2.7是2010年發(fā)布的,目前主要是用這個版本拌消。Python3是2006年開始開發(fā)挑豌,2008年發(fā)布,十年后的今天還沒有遷移完成墩崩,甚至主要是用的Python2而不是Python3氓英,這當(dāng)然不是Go2要走的路○谐铮看起來是因為缺乏向后兼容導(dǎo)致的問題债蓝,Python3刻意的和之前版本不兼容,比如print從語句變成了一個函數(shù)盛龄,string也變成了Unicode(這導(dǎo)致和C調(diào)用時會有很多問題)饰迹。沒有向后兼容芳誓,同時還是解釋型語言,這導(dǎo)致Python2和3的代碼混著用是不可能的啊鸭,這以為著程序依賴的所有庫必須支持兩個版本锹淌。Python支持from __future__ import FEATURE,這樣可以在Python2中用Python3的特性赠制。Python上可以學(xué)到的東西是:向后兼容是生死攸關(guān)的赂摆;和其他語言互操作的接口兼容是非常重要的;能否升級到新的語言是由調(diào)用的庫支持的钟些。
  • Perl6是2000年開始開發(fā)的烟号,15年后才正式發(fā)布,這也不是Go2應(yīng)該走的路政恍。這么漫長的主要原因包括汪拥,刻意沒有向后兼容,只有語言的規(guī)范沒有實現(xiàn)而這些規(guī)范不斷的修改篙耗。Perl上可以學(xué)到的東西是:不要學(xué)Perl迫筑;設(shè)置期限按期交付;別一下子全部改了宗弯。

特別說明的是脯燃,非常高興的是Go2不會重新走Python3的老路子,當(dāng)初被Python的版本兼容問題坑得不要不要的蒙保。

雖然上面只是列舉了各種語言的演進(jìn)辕棚,確實也了解得更多了,有時候描述問題本身邓厕,反而更能明白解決方案坟募。C和C++的向后兼容確實非常關(guān)鍵,但也不是他們能有今天地位的原因邑狸,C++11的新特性到底增加了多少DAU呢懈糯,確實是值得思考的。另外C++11加了那么多新的語言特性单雾,比如WebRTC代碼就是這樣赚哗,很多老C++程序員看到后一臉懵逼,和一門新的語言一樣了硅堆,是否保持完全的兼容不能做一點點變更屿储,其實也不是的。

應(yīng)該將Go的語言版本和標(biāo)準(zhǔn)庫的版本分開考慮渐逃,這兩個也是分別演進(jìn)的够掠,例如alias是1.9引入的向后兼容的特性,1.9之前的版本不支持茄菊,1.9之后的都支持疯潭。語言方面包括:

  • Language additions新增的特性赊堪,比如1.9新增的type alias。這些向后兼容的新特性竖哩,并不要求代碼中指定特殊的版本號哭廉,比如用了alias的代碼不用指定要1.9才能編譯,用之前的版本會報錯相叁。向后兼容的語言新增的特性遵绰,是依靠程序員而不是工具鏈來維護(hù)的,要用這個特性或庫升級到要求的版本就可以增淹。
  • Language removals刪除的特性椿访。比如有個提案#3939去掉string(int),字符串構(gòu)造函數(shù)不支持整數(shù)虑润,假設(shè)這個在Go1.20版本去掉成玫,那么Go1.20之后這種string(1000)代碼就要編譯失敗了。這種情況沒有特別好的辦法能解決端辱,我們可以提供工具,將代碼自動替換成新的方式虽画,這樣就算庫維護(hù)者不更新舞蔽,使用者自己也能更新。這種場景引出了指定最大版本码撰,類似C的-std=C90渗柿,可以指定最大編譯的版本比如-lang=go1.19荆姆,當(dāng)然必須能和Go1.20的代碼鏈接必盖。指定最大版本可以在go.mod中指定,這需要工具鏈兼容歷史的版本剔宪,由于這種特性的刪除不會很頻繁柴梆,維護(hù)負(fù)擔(dān)還是可以接受的陨溅。
  • Minimum language version最小要求版本。為了可以更明確的錯誤信息绍在,可以允許模塊在go.mod中指定最小要求的版本门扇,這不是強制性的,只是說明了這個信息后編譯工具能明確的給出錯誤偿渡,比如給出應(yīng)該用具體哪個版本臼寄。
  • Language redefinitions語言重定義。比如Go1.1時溜宽,int在64位系統(tǒng)中長度從4字節(jié)變成了8字節(jié)吉拳,這會導(dǎo)致很多潛在的問題。比如#20733修改了變量在for中的作用域适揉,看起來是解決潛在的問題留攒,但也可能會引入問題煤惩。引入關(guān)鍵字一般不會有問題,不過如果和函數(shù)沖突就會有問題稼跳,比如error: check盟庞。為了讓Go的生態(tài)能遷移到Go2,語言重定義的事情應(yīng)該盡量少做汤善,因為我們不再能依賴編譯器檢查錯誤什猖。雖然指定版本能解決這種問題,但是這始終會導(dǎo)致未知的結(jié)果红淡,很有可能一升級Go版本就掛了不狮。我覺得對于語言重定義,應(yīng)該完全禁止在旱。比如#20733可以改成禁止這種做法摇零,這樣就會變成編譯錯誤,可能會幫助找到代碼中潛在的BUG桶蝎。
  • Build tags編譯tags驻仅。在指定文件中指定編譯選項,是現(xiàn)有的機制登渣,不過是指定的release版本號噪服,它更多是指定了最小要求的版本,而沒有解決最大依賴版本問題胜茧。
  • Import go2導(dǎo)入新特性粘优。和Python的特性一樣,可以在Go1中導(dǎo)入Go2的新特性呻顽,比如可以顯示的導(dǎo)入import "go2/type-aliases"雹顺,而不是在go.mod中隱式的指定。這會導(dǎo)致語言比較復(fù)雜廊遍,將語言打亂成了各種特性的組合嬉愧。而且這種方式一旦使用,將無法去掉喉前。這種方式看起來不太適合Go英染。

如果有更多的資源來維護(hù)和測試,標(biāo)準(zhǔn)庫后續(xù)會更快發(fā)布被饿,雖然還是6個月的周期四康。標(biāo)準(zhǔn)庫方面的變更包括:

  • Core standard library核心標(biāo)準(zhǔn)庫。有些和編譯工具鏈相關(guān)的庫狭握,還有其他的一些關(guān)鍵的庫闪金,應(yīng)該遵守6個月的發(fā)布周期,而且這些核心標(biāo)準(zhǔn)庫應(yīng)該保持Go1的兼容性,比如os/signal哎垦、reflect囱嫩、runtimesync漏设、testing墨闲、timeunsafe等等郑口。我可能樂觀的估計net, os, 和syscall不在這個范疇鸳碧。
  • Penumbra standard library邊緣標(biāo)準(zhǔn)庫。它們被獨立維護(hù)犬性,但是在一個release中一起發(fā)布瞻离,當(dāng)前核心庫大部分都屬于這種。這使得可以用go get等工具來更新這些庫乒裆,比6個月的周期會更快套利。標(biāo)準(zhǔn)庫會保持和前面版本的編譯兼容,至少和前面一個版本兼容鹤耍。
  • Removing packages from the standard library去掉一些不太常用的標(biāo)準(zhǔn)庫肉迫,比如net/http/cgi等。

如果上述的工作做得很好的話稿黄,開發(fā)者會感覺不到有個大版本叫做Go2喊衫,或者這種緩慢而自然的變化逐漸全部更新成了Go2。甚至我們都不用宣傳有個Go2抛猖,既然沒有C2.0為何要Go2.0呢格侯?主流的語言比如C鼻听、C++和Java從來沒有2.0财著,一直都是1.N的版本,我們也可以模仿他們撑碴。事實上撑教,一般所認(rèn)為的全新的2.0版本,若出現(xiàn)不兼容性的語言和標(biāo)準(zhǔn)庫醉拓,對用戶也不是個好結(jié)果伟姐,甚至還是有害的。

Links

由于簡書限制了文章字?jǐn)?shù)亿卤,只好分成不同章節(jié):

  • Overview 為何Go有時候也叫Golang?為何要選擇Go作為服務(wù)器開發(fā)的語言愤兵?是沖動?還是騷動排吴?Go的重要里程碑和事件秆乳,當(dāng)年吹的那些牛逼,都實現(xiàn)了哪些?
  • Could Not Recover 君可知屹堰,有什么panic是無法recover的肛冶?包括超過系統(tǒng)線程限制,以及map的競爭寫扯键。當(dāng)然一般都能recover睦袖,比如Slice越界、nil指針荣刑、除零馅笙、寫關(guān)閉的chan等。
  • Errors 為什么Go2的草稿3個有2個是關(guān)于錯誤處理的嘶摊?好的錯誤處理應(yīng)該怎么做延蟹?錯誤和異常機制的差別是什么?錯誤處理和日志如何配合叶堆?
  • Logger 為什么標(biāo)準(zhǔn)庫的Logger是完全不夠用的阱飘?怎么做日志切割和輪轉(zhuǎn)?怎么在混成一坨的服務(wù)器日志中找到某個連接的日志虱颗?甚至連接中的流的日志沥匈?怎么做到簡潔又夠用?
  • Interfaces 什么是面向?qū)ο蟮腟OLID原則忘渔?為何Go更符合SOLID高帖?為何接口組合比繼承多態(tài)更具有正交性?Go類型系統(tǒng)如何做到looser, organic, decoupled, independent, and therefore scalable畦粮?一般軟件中如果出現(xiàn)數(shù)學(xué)散址,要么真的牛逼要么裝逼。正交性這個數(shù)學(xué)概念在Go中頻繁出現(xiàn)宣赔,是神仙還是妖怪预麸?為何接口設(shè)計要考慮正交性?
  • Modules 如何避免依賴地獄(Dependency Hell)儒将?小小的版本號為何會帶來大災(zāi)難吏祸?Go為什么推出了GOPATH、Vendor還要搞module和vgo钩蚊?新建了16個倉庫做測試贡翘,碰到了9個坑,搞清楚了gopath和vendor如何遷移砰逻,以及vgo with vendor如何使用(畢竟生產(chǎn)環(huán)境不能每次都去外網(wǎng)下載)鸣驱。
  • Concurrency & Control 服務(wù)器中的并發(fā)處理難在哪里?為什么說Go并發(fā)處理優(yōu)勢占領(lǐng)了云計算開發(fā)語言市場蝠咆?什么是C10K踊东、C10M問題?如何管理goroutine的取消、超時和關(guān)聯(lián)取消递胧?為何Go1.7專門將context放到了標(biāo)準(zhǔn)庫碑韵?context如何使用,以及問題在哪里缎脾?
  • Engineering Go在工程化上的優(yōu)勢是什么祝闻?為什么說Go是一門面向工程的語言?覆蓋率要到多少比較合適遗菠?什么叫代碼可測性联喘?為什么良好的庫必須先寫Example?
  • Go2 Transition Go2會像Python3不兼容Python2那樣作嗎辙纬?C和C++的語言演進(jìn)可以有什么不同的收獲豁遭?Go2怎么思考語言升級的問題?
  • SRS & Others Go在流媒體服務(wù)器中的使用贺拣。Go的GC靠譜嗎蓖谢?Twitter說相當(dāng)?shù)目孔V,有圖有真相譬涡。為何Go的聲明語法是那樣闪幽?C的又是怎樣?是拍的大腿涡匀,還是拍的腦袋盯腌?
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者陨瘩。
  • 序言:七十年代末腕够,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子舌劳,更是在濱河造成了極大的恐慌帚湘,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒿囤,死亡現(xiàn)場離奇詭異客们,居然都是意外死亡崇决,警方通過查閱死者的電腦和手機材诽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恒傻,“玉大人脸侥,你說我怎么就攤上這事∮澹” “怎么了睁枕?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我外遇,道長注簿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任跳仿,我火速辦了婚禮诡渴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘菲语。我一直安慰自己妄辩,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布山上。 她就那樣靜靜地躺著眼耀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪佩憾。 梳的紋絲不亂的頭發(fā)上哮伟,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天,我揣著相機與錄音妄帘,去河邊找鬼澈吨。 笑死,一個胖子當(dāng)著我的面吹牛寄摆,可吹牛的內(nèi)容都是我干的谅辣。 我是一名探鬼主播,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼婶恼,長吁一口氣:“原來是場噩夢啊……” “哼桑阶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起勾邦,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤蚣录,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后眷篇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體萎河,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年蕉饼,在試婚紗的時候發(fā)現(xiàn)自己被綠了虐杯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡昧港,死狀恐怖擎椰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情创肥,我是刑警寧澤达舒,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布值朋,位于F島的核電站,受9級特大地震影響巩搏,放射性物質(zhì)發(fā)生泄漏昨登。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一贯底、第九天 我趴在偏房一處隱蔽的房頂上張望篙骡。 院中可真熱鬧,春花似錦丈甸、人聲如沸糯俗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽得湘。三九已至,卻和暖如春顿仇,著一層夾襖步出監(jiān)牢的瞬間淘正,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工臼闻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鸿吆,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓述呐,卻偏偏與公主長得像惩淳,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子乓搬,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Others 關(guān)于Go思犁,還有哪些重要的技術(shù)值得了解的,下面詳細(xì)分享进肯。 GC GC一般是C/C++程序員對于Go最常...
    winlinvip閱讀 1,387評論 1 0
  • 今天感恩節(jié)哎激蹲,感謝一直在我身邊的親朋好友。感恩相遇江掩!感恩不離不棄学辱。 中午開了第一次的黨會,身份的轉(zhuǎn)變要...
    迷月閃星情閱讀 10,559評論 0 11
  • 彩排完环形,天已黑
    劉凱書法閱讀 4,197評論 1 3
  • 沒事就多看看書策泣,因為腹有詩書氣自華,讀書萬卷始通神斟赚。沒事就多出去旅游着降,別因為沒錢而找借口差油,因為只要你省吃儉用拗军,來...
    向陽之心閱讀 4,777評論 3 11
  • 表情是什么任洞,我認(rèn)為表情就是表現(xiàn)出來的情緒。表情可以傳達(dá)很多信息发侵。高興了當(dāng)然就笑了交掏,難過就哭了。兩者是相互影響密不可...
    Persistenc_6aea閱讀 124,444評論 2 7