這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
對於一個不穩定的語言,刪刪改改什麼的都是常事。即便是穩定的語言,也逃不過隔三差五整修一下的命運。於是 Golang 大修是個麻煩。
用 Golang 的好處是你正在使用世界上最聰明的一群科學家和工程師的傑作。於是,升級這些麻煩事變得不那麼麻煩了,因為有了 gofix。
原文在此:http://blog.golang.org/2011/04/introducing-gofix.html
——————————-翻譯分割線——————————-
gofix介紹
下一個 Go 的發布版將會包含多個官方 Go 包 API 的重大變化。實現 HTTP 伺服器處理、調用 net.Dial、調用 os.Open,或者使用反射的代碼如果不使用新的 API 升級,將無法編譯。現在的發布已經相當穩定並且不那麼頻繁了,這將會成為一個常態。每次的 API 變化發生在每周的快照版本之間,並且可控;總之,無論如何,這帶來了大量需要手工更新的已有代碼。
gofix 是一個減少了大量升級已有代碼工作的新工具。它從原始碼中讀取程式,尋找舊的 API,用當前 API 改寫它們,然後將程式寫迴文件。並不是所有的 API 變化都儲存了下來,所以 gofix 並不是總能良好的工作。當 gofix 不能改寫舊的 API,它列印一條警告,給出檔案名稱和行號,這樣開發人員可以檢查並改寫代碼。gofix 處理那些簡單的、重複的、冗長的修改,這樣開發人員可以集中精力對付那些真正值得注意的東西。
每次 API 發生了重大變化,都會添加代碼到 gofix 來儘可能的處理轉換。當升級到新的 Go 發布版本,而已有代碼無法編譯,只要在代碼目錄上執行 gofix。
也可以擴充 gofix 以支援自有 API 的改動。gofix 程式是一個簡單的驅動調用修複擴充,每個擴充都處理一個特定的 API 變更。現在,編寫新的修複需要掃描和改寫 go/ast 文法樹,通常複雜程度跟 API 變更程度成正比。如果想要瞭解,netdialFix、osopenFix、 httpserverFix 和reflectFix 是說明樣本,從易到難的順序。
當然,同樣也是 Go 代碼,我們的代碼跟你的一樣受到這些 API 變化的影響。通常,我們在 API 變化的同時編寫 gofix 支援,然後用 gofix 改寫主代碼樹中使用到的地方。我們在其他 Go 代碼和個人項目中使用 gofix 進行升級。我們甚至使用 gofix 對 Google 的內部代碼樹進行更新,當它跟新的發布版本有衝突不能編譯的時候。
作為一個例子,gofix 可以改寫這個來自於 fmt/print.go 的程式碼片段:
switch f := value.(type) {case *reflect.BoolValue: p.fmtBool(f.Get(), verb, field)case *reflect.IntValue: p.fmtInt64(f.Get(), verb, field)// ...case reflect.ArrayOrSliceValue: // Byte slices are special. if f.Type().(reflect.ArrayOrSliceType).Elem().Kind() == reflect.Uint8 { // ... } // ...}
使其能夠配合新的反射 API:
switch f := value; f.Kind() {case reflect.Bool: p.fmtBool(f.Bool(), verb, field)case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: p.fmtInt64(f.Int(), verb, field)// ...case reflect.Array, reflect.Slice: // Byte slices are special. if f.Type().Elem().Kind() == reflect.Uint8 { // ... } // ...}
上面的幾乎每一行都有一些微小的修改。大面積的改動的變化是機械化一致的,就是那種電腦非常擅長的工作。
gofix 可以這麼做的原因是 Go 在標準庫中支援解析 Go 原始碼到文法樹,同時也支援將這些文法樹列印成 Go 原始碼。特別是,Go 輸出庫用官方格式輸出程式(通常是 gofmt 工具完成的),允許 gofix 對 Go 程式進行自動修改,而不會導致格式異常。事實上,建立 gofmt 的動機之一(可能另一個是避免爭論大括弧應該在哪)是建立一個能夠更加容易重寫 Go 程式的工具,就像 gofix 做的那樣。
gofix 已經讓它變得不可或缺。特別是近期反射的修改,在沒有自動化轉換的情況下可能相當令人不快,而反射 API 極為需要重新處理。gofix 提供了修複錯誤或者完全重構包的 API 的能力,而無須擔心現有代碼轉換的問題。我們希望你能像我們一樣,發現 gofix 是一個有用並且方便的工具。
– Russ Cox,四月 2011