• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-90  評論-947  文章-0  trackbacks-0

            (原發于 GitHub Pages,2019-01-01 23:22:43)

            2019 年,我回來了。

            不知不覺中,我入 PHP 的坑已經 3 年有余,入 Go 的坑也大半年了。作為不評論不舒服斯基星人,自然要對 Go 品頭論足一番的。

            總的一句話,Go 的一些特性確實恰到好處,然而更多的地方卻是平庸、繁瑣、束縛,以至于我想不到它是適合哪些場景的。

            靜態語言里,C、C++ 有著明顯的適用領域:你要想老老實實寫程序,不玩任何花招,就用 C 吧,至少你能掌控一切,實在想玩你還有宏這個大殺器;你要想玩點花招,那就用 C++,代價就是需要自身水平更高,能掌控到多大層次就寫多大層次,不懂的不要不懂裝懂去用,總體來說還是安全的。

            腳本語言里,如果要隨便寫點什么工具,python 啥的挺方便的;寫點網絡的,就用世界上最好的語言 PHP 吧。什么?你說 Java?實在沒辦法,體量太大,公司要你用你就用吧。不過就其本質而言,其實 Java 和今天的主角——Go 是同一類的。不是說他們語法像,是指應用場景(不過這個領域拿 PHP 寫顯然會更爽)。

            嗯——為了表達出真實的意思,我想用詞稍微犀利點,請先做一下心理建設。

            我不怎么懂 Java,就我淺薄的了解而言,如果你的公司、團隊有很多傻逼,甚至你自己也是,業務上又正好可以用 Java 界的一些現成的框架、組件,那么用 Java 肯定是沒錯的啦。它確實有一種魔力,讓你無論多傻逼,也絕對寫不出錯得多么隱蔽、精妙無比的代碼;同時讓你無論多牛逼,也寫不出多么精彩絕倫、言簡意賅的代碼。Go 也有這種特質,甚至有些地方比起 Java 更有過之而不及。不信請看:

            別人家的寫法:

            r = f(p1, p2 != null ? p2 : p3)
            
            $r = f($p1, $p2 ?? $p3) 
            

            Go 家的寫法:

            var r someType
            if p2 != nil {
            	r = f(p1, p2)
            } else {
            	r = f(p1, p3)
            }
            

            為什么要設計成這樣?Go 爸爸說:你們有些人啊,會嵌套很多層 ?:,導致代碼可讀性太差啦,于是禁止你們使用 ?:,這是家法。在這里,作為熊孩子的代表,我來告訴大家怎樣寫出讓 Go 爸爸無語的代碼:

            	foo := 1
            	bar := 2
            	var foobar int
            	if foo > bar { if bar > 1 { foobar = 1 } else if bar < 0 { foobar = 2 } else { foobar = 3 } } else { if foo >= 3 { foobar = 4 } else { foobar = 5 } }
            

            怎么樣?可讀性差不差?

            看到了吧,這種傻逼是防不住的,他愿意把 ?: 嵌套好多層,它同樣可能會把 if else 嵌套好多層。有素質的人會怎么做?遇到 ?: 嵌套太多立馬拆成 if else。所以結論是,即使去掉 ?:,傻逼還是傻逼,但是正常的人寫代碼就會很啰嗦;支持 ?:,傻逼還是傻逼,正常人用起來爽。要知道一層 ?: 的場景占所有 ?: 場景的比例還是很高的吧。我覺得可以這樣,Go 爸爸可以統計一些工業級代碼庫的 ?: 嵌套層數,作為數據支撐(比如自家 Chrome 里一層 ?: 占 95%,兩層占 4.9),然后再在語言層面只支持一層 ?:,編譯參數可選打開兩層,不支持兩層以上。這就功在千秋了。

            除了 不支持 ?:,Go 爸爸還有很多這樣的設計,隨便舉幾個例子:

            1. 不支持默認參數
            2. 不支持運算符重載
            3. 不提供 goroutine id(以及 gls、可重入鎖)

            特別是第三點,也是這種思路,因為你們可能會濫用,所以我不提供。類似這種“爸爸思路”,是我今天要噴的最大噴點。前兩點也許是抄 Java 的,不怪 Go 爸爸。

            綜上,Go 爸爸通過扼殺一些基本語法或者一些基礎信息,來防止傻逼干壞事,同時讓正常人用起來很啰嗦,同時還可能防止不了傻逼干壞事。這跟 Java 通過不提供高級語法來防止傻逼干壞事是師出同門啊,而且他們正好都能寫網絡服務程序,你說它們像不像?

            然而,Go 爸爸也有精分的時候,它居然發明語法糖了耶!比如 if 可以執行一個句句。單就這個語法而言,我的態度是中立偏贊。贊是贊 Go 爸爸確實用過心了,某些時候挺方便,還能縮小變量作用域;不過這個總歸是可有可無的,畢竟換一行寫也不會死,要變量作用域加個大括號就行。

            小語法方面倒是有個亮點,那就是 switch 的隱式 break、顯式 fallthrough 處理。不多展開了。

            除了防傻逼,Go 爸爸還有一個思路,就是只許州官放火,不許百姓點燈。有兩個語法點——

            1. 泛型
            2. 逗號ok斷言

            先說泛型吧。不支持泛型其實我挺能理解的,因為他確實比 ?: 復雜多了,傻逼用不起,?: 都沒有,怎么可能會有泛型呢。然而 Go 爸爸有特權呀,它的 map、chan 可都是泛型的哦。但是你要寫一個泛型的語法結構的話,對不起沒有。

            再說逗號ok斷言,同樣 Go 爸爸要得起,我們要不起。其實我更想要一個這樣的語法:當返回值是 xxx, ok 或者 xxx, err 的時候,我如果用一個返回值接,那么就返回第一個,以便鏈式調用,同時 !ok 或者 err != nil 的時候 panic。

            以上兩小點雖然是在噴,不過還好啦。無所謂的。下面講幾個大的方面。

            代碼組織

            我特別贊賞 Go 對于 package 級嚴格的循環依賴檢查。然而如果加上其他規則:

            • 一個目錄一個 package
            • 不同路徑下的同名目錄也是不同 package
            • go 代碼無法拆成 .h、.cpp

            實際可操作性就會非常差。要拆 package,就要把依賴關系梳理得特別嚴格,半點不得馬虎。這對工一般的程代碼來說是個極大的挑戰。

            我更傾向于做成函數級循環依賴檢查,或者不限制(畢竟遞歸函數也是要支持的嘛)。

            這部分,中立偏噴,偏噴是因為 Go 爸爸用了我的小名 internal。

            OOP

            我特別贊賞 Go 對于 OOP 泛濫成災的思考與探索,以及對于終結這陣 Java 帶來的不正之風的決心。怎么可能萬物都是 class 呢。但同時,Go 還是有點矯枉過正的,如果我需要利用傳統的 OOP 來搞事情,就非常麻煩,你甚至都無法寫出一個框架來。你只能寫庫讓別人用。雖然我也不喜歡框架,但有的時候是需要框架的。

            defer 非常切中痛點,特別解決一堆錯誤 return 外加資源釋放的問題。相比之下C 里只能用 goto,C++ 本身不支持但可以玩出 LOKI_ON_BLOCK_EXIT 或者 BOOST_SCOPE_EXIT。defer 一舉解決問題。(要是能再增加命名 defer 以及撤銷 defer 的功能就更好了。沒錯,你也許看出來了,我覺得 LOKI_ON_BLOCK_EXIT 是最完美的方案。)

            雖然 defer 很好,但不意味著析構就沒用武之地了。理想的情況是,析構、多態、defer 都要有……

            這部分我的態度是中立。

            錯誤處理

            終于要點贊了。錯誤處理是在我看來 go 完勝的地方,恰到好處地處理問題,又防止濫用。也矯正 Java 帶來的歪風邪氣。

            Java 的設計,讓人不得不用異常來處理業務。甚至 Java 自己還幫我們分好類了:一種是不是異常的異常,用來處理業務;另一種是真的異常。一些用慣 Java 的傻逼跑到 C++、PHP、Python 里亂拉屎,到處是 try catch。

            Go 爸爸一聲令下,萬籟俱寂。

            goroutine

            最后不得不說說 gorouthine,畢竟是賣點嘛。我的態度中立偏贊。贊是因為這是一種太有創意的方案,居然想在在語言層面解決多線程、并發問題;不過我還是覺得這更多的是應用層面的問題,做到官方庫里會更好,而不是做成語法。

            總結

            剛開始用 Go 的時候,特別亮眼,簡直處處是亮點,然后越接觸越討厭,一點也不耐看……看得出來,設計者糅合了 C、python、Java 的一些特性,并融入了自己的獨特的理解。Go的設計者真的特別特立獨行且堅持己見,一些我喜歡的特性因為他們的堅持而存在下來,一些我討厭的特性也因為他們的堅(Gu)持(Zhi)而不能有所改觀。就這樣的 Go,想代替 C 作為系統語言,是沒戲的;想在網絡服務有一番作為,搶 Java 的份額,或許是有機會的,不過最多只能搶 Java 的,連 C# 的都搶不了,C++、PHP 更搶不了。

            嗯,除了特定的不得不用的場合,反正我是不會特意用 Go 的。

            2019,新年快樂!

            posted on 2020-09-20 14:16 溪流 閱讀(4469) 評論(0)  編輯 收藏 引用 所屬分類: Golang
            久久久久免费精品国产| 久久强奷乱码老熟女网站| 精品欧美一区二区三区久久久| 久久久久久久女国产乱让韩| 久久露脸国产精品| 亚洲国产成人久久笫一页| 青青青青久久精品国产h| 国产99久久精品一区二区| 少妇人妻88久久中文字幕| 97视频久久久| 亚洲午夜无码AV毛片久久| 久久99久久无码毛片一区二区| 久久久久国产| 欧洲国产伦久久久久久久| 久久综合精品国产一区二区三区 | 欧美国产成人久久精品| 亚洲人成无码www久久久| 久久狠狠爱亚洲综合影院 | 国产成人久久精品区一区二区| 一本久道久久综合狠狠爱| 国产亚洲精品久久久久秋霞| 中文字幕精品久久| 精品久久久一二三区| 久久综合88熟人妻| 久久久久97国产精华液好用吗| 久久久久久精品免费看SSS| 国产精品久久久久aaaa| 欧美日韩精品久久久久| 久久99精品久久久久子伦| 久久国产精品99精品国产| 丁香久久婷婷国产午夜视频| 一本久道久久综合狠狠躁AV| 久久狠狠色狠狠色综合| 久久精品国产AV一区二区三区| 久久中文字幕一区二区| 老男人久久青草av高清| 亚洲欧洲久久av| 一本综合久久国产二区| 亚洲欧洲久久av| 一本大道久久香蕉成人网| 色偷偷88欧美精品久久久|