《我不喜歡Go語言的十個理由》 by Lawrence 2019/06/17java
《我不喜歡「我不喜歡 Go 語言的十個理由」的十個理由》 by Wzy_CC 2020/07/08程序員
我不喜歡Go語言的十個理由做者Lawrence使用了三年Go語言,而且參與了多個大型Go的項目。可是他如今放棄了Go而且認爲Go「在很差的方面使人沒法忍受」。可是其中一些理由我認爲有點牽強,View1-10分別是做者的十個不喜歡Go語言的理由:數組
Go 語言使用首字母大小寫來決定標識符的可見性app
對包外暴露的變量和方法使用大小寫來區分公私有,這實際上是很是聰明的作法,不但減小了關鍵字的個數,並且使得總體看起來簡介優雅。函數
若是從java或者C++轉爲go開發,天然會對缺乏public
和private
關鍵字而不適應,對於做者認爲的首字母大寫應該「含有其餘含義」,對此go語言規範中對於包名,函數名和變量名都認爲應當使用小寫,則此時大寫的方法和變量天然暴露在包外提供訪問,常量大寫是慣例,依舊由const
關鍵字進行區分,並非太大的問題post
做者認爲下列代碼由於小寫字母而變得糟糕:設計
type user struct { name string } func main() { var user *user user = &user{} // Compile error }
上述代碼中user是私有結構體,而結構體的變量則是user,在編譯中產生錯誤,把user類型看成user變量而沒法經過編譯。事實上這也並非大問題。任何這種隨意起變量名而不加以區分不帶有實際意義的聲明,在任何語言的代碼中都是極其糟糕的。3d
命名方式是開發者的習慣,若是由於核心開發成員中有人習慣短命名的方式而攻擊語言的話,是否是本末倒置了一點。code
結構體不會顯式聲明瞭它實現了哪些接口,而是經過匹配方法簽名來鑑別對象
Go自己沒有類,說什麼你都對。
Go語言沒有異常,而是經過多個返回值來返回錯誤
這偏偏時Go區別於其餘語言的一大特性,他要求開發者必須關注並顯式處理可能存在的錯誤,並且做者錯誤的認爲能夠將err賦值給_,這種錯誤處理方式正是所提倡的提醒開發者,而不會使開發者」忘記「檢查返回值中是否是包含了錯誤,徹底屬於開發者本身的代碼不夠健壯,而非語言自己的缺陷。
做者在下面代碼中認爲,並不保證user和err包含正確的值,user可能沒有被賦值
user, err := getUserById(userId)
超出個人理解,也不能明白在其餘語言中未被賦值能夠經過某種方式檢查出來而不依賴反射Valueof
等方法?
Go代碼的神奇行爲
做者認爲湊巧把一個函數名定義爲init()
則會在運行時自動調用,的確在運行時init()
函數會先於主函數調用,若是顯式調用會報未定義的錯誤。推薦使用Init()
來進行對象和連接的初始化。Peter Bourgon認爲應該儘量減小init()
函數的使用。
由於首字母大寫約定,很容易出現不少相同的標識符
」一些包名、結構體名和變量名都叫做 item。在 Java 中,包名使用了全限定名,類名首字母是大寫的。有時候以爲 Go 代碼很差閱讀,由於可能沒法一會兒看出一個標識符的做用域是怎樣的。「
結構體變量名在同一個包內的重名在編譯時就沒法經過,至於包名別稱和變量的重名屬於開發習慣問題。
Go代碼經過編譯並不容易
編譯器太過嚴格從對開發者的要求上是好事,對於開發者的代碼水平來講,越嚴格的編譯器代碼質量越高,這絕對是go的優良特性之一。
Go語言沒有三元運算符(?:)
沒有三元運算,而轉換爲了繁雜的分支語句,的確變得不優雅了
sort接口很笨
自定義類型實現sort接口須要三個函數,而當存在十個結構體時則必須寫30個函數,做者認爲其中二十個是同樣的。這是由於go缺乏泛型,類比C++若是不存在模板,則實現排序一樣是一個災難。
做者認爲轉型看起來像是一個函數:
sort.Sort(sort.Reverse(UsersByLastSignedInAt(users)))
事實上理解爲函數傳遞對於理解也沒有任何問題。
缺乏泛型
增長泛型是社區呼聲最高的聲音,事實上在即將到來的2.0版本中會加入Go泛型。
沒有站在程序員的角度考慮問題
做者列舉了一個append函數的例子,其中append返回一個新數組:
users = append(users, newUser)
而做者認爲下面這行代碼總能調用成功是最糟糕的:
append(users, newUser)
由於函數在可能的狀況下進行原地數組修改,若是沒有足夠的空間就返回一個新數組。而這個糟糕的設計在最新的編譯器中已經修改了,當append
函數不做爲右值時在編譯時沒法經過。
HackerNews社區其餘的一些聲音
在項目中未導入的包和變量會致使編譯錯誤,強制給編譯器打補丁忽視錯誤是本質上的倒退,既然沒有使用爲何須要聲明呢,而這正式Go比PHP更容易維護的緣由
若是你要對一個片斷進行排序,sort.Slice
比sort.Interface
更好
任何一門語言中都不該該定義容易產生混淆的接口
語言沒有好壞,全看開發者喜不喜歡,業務需不須要。是否選擇一門語言,不要看它的設計,要看它是否能夠解決你的問題。
開發者喜歡的語言對於開發者來講固然是「好「的語言,而做者可能習慣於java的一些使用方法,且因爲go糖較少而使用不習慣,語法糖不是必需品。
關因而否應該在go中使用init()
函數,詳見《現代Go的一些理論》