Golang不利於重構升級? - fasterthanli

banq發表於2022-04-30

本文作者曾經發布《我想離開Golang先生的狂野之旅》,該文反覆出現在Reddit、Lobste.rs、HackerNews等地方引起廣泛爭議,本文是其最新文章,主要指出go雖然很容易上手,但是隨著系統複雜就很難擴充了,下面是摘錄:

顯然,Go團隊並不想設計一種語言。他們真正喜歡的是他們的非同步執行方式:他們希望能夠在此基礎上實現TCP、HTTP、TLS、HTTP/2和DNS等,然後在所有這些的基礎上實現網路服務。

所以他們並沒有打算設計一種真正語言。

Go只是需要讓 剛從學校畢業的Googlers熟悉,他們可能學過一些Java/C/C++/Python"(Rob Pike, Lang NEXT 2014),所以它借用了所有這些語言。

就像C語言一樣,它完全不關心錯誤處理:
所有的東西都是一個大的毛茸茸的可變狀態的泥球,你需要新增ifs和els來非常謹慎地(非常手動地)確保你不會傳播無效的資料。

可變狀態
就像 Java 一樣,它試圖消除“值”和“引用”之間的區別,因此無法從呼叫站點判斷某些內容是否發生了變異:

import "fmt"

type A struct {
    Value int
}

func main() {
    a := A{Value: 1}
    a.Change()
    fmt.Printf("a.Value = %d\n", a.Value)
}


上面程式碼依賴於下面兩種函式實現:

func (a A) Change() {
    a.Value = 2
}
func (a *A) Change() {
    a.Value = 2
}


而且,就像C和Java一樣,你不能決定什麼是可變的,什麼是不可變的(C中的const關鍵字基本上是諮詢性的,有點),傳遞一個引用(例如,為了避免昂貴的複製)充滿了風險,比如它從你腳下被變異,或者它被永遠儲存在某個地方,阻止它被釋放(一個較小,但非常真實的問題)。

Go未能防止許多其他型別的錯誤:它使人們很容易意外地複製一個mutex,使其完全失效,或者使結構欄位未被初始化(或者說,初始化為零值),導致無數的邏輯錯誤。

Rust和Go

  1. Go的成功在很大程度上是由於它有包括電池和意見的預設值。
  2. Rust的成功在很大程度上是由於它很容易被零散地採用,並與其他人打成一片。


他們都是成功的故事,只是非常不同。

Go 作為原型設計/入門語言
Go 很可能不足以用於生產服務,但肯定還是有一席之地的。
畢竟,Go 是一門容易上手的語言(因為它太小了,對吧?),而且現在很多人都學過它,所以很容易招募 Go 開發人員,所以我們可以以便宜的價格獲得大量的開發人員開發幾個原型系統?

然後當事情變得困難時(就像他們總是大規模地做的那樣),我們要麼將其重寫(重構)為其他東西,要麼我們會聘請專家,我們會想出辦法。

我所見過的所有工程組織都非常不喜歡重寫(重構),這是有原因的!他們需要時間,協調無縫過渡是很難的,細節會在混亂中丟失,你在做這些的時候並沒有交付新的功能,你必須重新培訓你的員工來有效地處理新的功能。
他們需要時間,安排一個無縫的過渡是很難的,細節會在混亂中丟失,你在做這些事情的時候不會產生新的功能,你必須重新培訓你的員工,使他們在新的事情上有效等等。

所以很少有東西最終會被重寫(重構)。
隨著越來越多的元件用Go編寫,有越來越多的理由繼續這樣做:不是因為它對你的工作特別好,而是因為與現有程式碼庫的互動,從字面上看,其他任何東西都是非常痛苦的。

所有 Go 的陷阱,語言和編譯器無法幫助您預防的所有事情,對每個人來說都是一個問題,無論是新手還是經驗豐富的人。

因為Go有很多值得喜歡的地方,因為它很容易上手,但卻很難離開,因為當初選擇它的代價會隨著時間的推移慢慢顯現出來,而且會不斷增加,直到為時已晚才會變得難以忍受,作為一個行業,這不是我們可以忽視的討論。

詳細點選標題

相關文章