Go語言并不簡單
Go 不是一種很簡單的編程語言。盡管它的許多方面都很簡單:語法很簡單,大多數語義也很簡單。然而,語言不僅僅是語法,我們希望利用它編寫出實用的代碼。利用 Go 編寫有用的代碼并不總是那么容易

事實證明,通過某種方式將一些簡單的功能組合在一起,編寫出有用的代碼可能會非常棘手。在 Ruby 中,如何刪除某個數組中的一項?list.delete_at(i)。如何通過值刪除條目?list.delete(value)。非常簡單!
然而在 Go 中,事情可沒有那么容易,為了刪除索引 i,你需要執行以下操作:

為了刪除值 v,你必須使用循環:

這未免也太復雜了?也未必,我認為即使沒有 Go 語言經驗,大多數程序員也可以看懂上述代碼。但它確實不簡單。我這個人比較懶,我會從 SliceTricks 上復制這類代碼,因為我想專心解決實際問題,不想為這類小事苦惱。
此外,Go 語言也很容易出現使用錯誤或性能不佳的情況,特別是對于經驗不足的程序員而言。例如,我們來比較一下:將上述復制到一個新數組,和復制到一個新的預分配數組

盡管在大多數情況下 1529ns 足夠快了,而且也不必過分擔心,但是在許多情況下,性能確實很重要,而且擁有能保證實現最佳性能的 list.delete(value)是非常有必要的。
圖片
再舉一個例子:goroutine。“使用 goroutine 并不難,你只需要添加關鍵字 go,就可以了!”沒錯,這樣確實可以了,但是如果我需要同時運行 500 萬個 goroutine 呢?到時候,你會納悶,所有內存都去哪兒了?而且你很難避免意外“泄漏”goroutine。
有許多模式可以限制 goroutine 的數量,但哪一種都不簡單。下面就是一個簡單的例子:

我加了一些注釋是有原因的:對于不熟悉 Go 的人來說,這段代碼非常難以理解。上述代碼也不能確保數字會按照一定的順序輸出(這可能是一項需求,當然也可能不是)。
Go 的并發原語很簡單且易于使用,但是將它們組合起來,解決常見的現實問題就沒有那么簡單了。
RichHickey 在“Simple Made Easy”中提出,我們不應該將“簡單”與“易于編寫”混為一談:即便你只需編寫一兩行代碼,也并不意味著底層的概念很簡單(這里的簡單指的是淺顯易懂)。
這句話值得人尋味。在大多數情況下,我們不應該為了“易于編寫”而犧牲“簡單”。但這并不意味著我們不應該考慮如何讓編程更加簡單。即便概念很簡單,也并不意味著易于使用,人們可能會錯誤地使用,或使用的方式會引發 bug。將 Hickey 的論點推到極致,就會出現 Brainfuck 之類語言,當然這很愚蠢。
理想情況下,編程語言應該減少推理其行為所需的認知負擔,增加這種認知負擔的方法有很多:復雜的語言功能就是其中之一;而人們不得不花費精力實現一些簡單的概念也是一種負擔,因為我需要多考慮一段代碼。盡管我不太關心代碼格式或語法選擇,但我認為減少閱讀代碼時的認知負擔很重要。
缺少泛型是導致 Go 不那么簡單的部分原因。現在很難實現 slices 包之類以通用的方式完成的操作。而泛型可以讓這成為可能,同時也會讓編程變得更復雜(使用了更多的語言功能),但是它們也可以讓編程更加容易,并降低其他方面的復雜性。
這些是無法克服的問題嗎?不,我仍然會使用 Go,而且也會一如既往地喜歡 Go。但是,我不認為 Go 是你“可以在 5~10 分鐘之內學會的語言”。
歸根結底,學習語言不僅僅要學習編寫 if 和 for 的語法,你需要學習的是思維方式。我見過許多 Python 或 C#開發人員嘗試在 Go 語言中實現那些語言的某些概念或模式。常見的做法包括將結構嵌入作為繼承,將 panics 作為異常,通過 interface{}實現“偽動態編程”等等。這些做法很難取得良好的結果。
當第一次編寫 Go 程序時,我也犯了同樣的錯誤,這是很自然的事情。在剛接觸 Ruby 的時候,我曾嘗試用 Ruby 編寫 Python 代碼(由于這兩種語言很相似,所以結果相對好一點,但仍然有很多奇怪的做法,比如使用 for 循環)。
這就是為什么我不喜歡人們通過 Go 教程學習這門語言的原因,教程只會講解基本的語法,還有其他的一些知識。這只能讓你大致感受一下 Go 語言,但并不能幫助你真正學習這門語言
文章來源于網絡,侵刪!
