Go 1 16中Module功能新變化

2021-10-19 14:26:23 字數 4178 閱讀 1987

原文:

翻譯:kevin

希望您喜歡go 1.16! 這個版本有很多新功能,特別是對module而言。發行說明中簡要介紹了這些變化,但讓我們深入發掘一下其中的一些變化。

go命令現在預設以module-aware模式構建包,即使沒有go.mod檔案存在。這是向在所有專案中使用module功能邁出的一大步。

通過設定go111module環境變數為off,仍然可以在gopath模式下構建包。你也可以將go111module設定為auto,只有當當前目錄或任何父目錄中存在go.mod檔案時才啟用module-aware模式。這在以前是預設的。請注意,您可以使用go env -w來永久地設定go111module和其他變數。

go env -w go111module=auto
我們計畫在 go 1.17 中放棄對gopath模式的支援。換句話說,go 1.17將忽略go111module。如果您的專案沒有以module-aware模式構建,現在是時候遷移了。如果有問題妨礙您遷移,請考慮提交問題或體驗報告。

在之前的版本中,當go命令發現go.modgo.sum有問題時,比如缺少require指令或缺少sum,它會嘗試自動修復問題。我們收到了很多反饋,認為這種行為是出乎大家意料的,尤其是對於像go list這樣通常不會產生***的命令。自動修復並不總是可取的:如果乙個匯入的包沒有被任何需要的module提供,go命令會新增乙個新的依賴關係,可能會觸發普通依賴關係的公升級。即使是拼寫錯誤的匯入路徑也會導致(失敗的)網路查詢。

在 go 1.16 中,module-aware命令在發現go.modgo.sum中的問題後會報告乙個錯誤,而不是嘗試自動修復問題。在大多數情況下,錯誤資訊建議使用命令來修復問題。

$ go build

example.go:3:8: no required module provides package golang.org/x/net/html; to add it:

go get golang.org/x/net/html

$ go get golang.org/x/net/html

$ go build

和之前一樣,如果存在vendor目錄,go命令可能會使用該目錄(詳見vendoring)。像go getgo mod tidy這樣的命令仍然會修改go.modgo.sum,因為它們的主要目的是管理依賴關係。

go install命令現在可以通過指定@version字尾來安裝特定版本的可執行檔案。

go install golang.org/x/tools/[email protected]
當使用這種語法時,go install命令會從該module的制定版本安裝,而忽略當前目錄和父目錄中的任何 go.mod 檔案。(如果沒有@version字尾,go install會像往常一樣繼續執行,使用當前module的go.mod中列出的版本要求和替換來構建程式。)

我們曾經推薦使用go get -u程式來安裝可執行檔案,但這種使用方式對go.mod中新增或更改module版本需求的意義造成了太多的混淆。而為了避免意外修改go.mod,人們開始建議使用更複雜的命令,比如:

cd $home; go111module=on go get program@latest
現在我們都可以用go install program@latest來代替。詳情請看go install。

為了消除使用哪個版本的歧義,當使用這種安裝語法時,對程式的go.mod檔案中可能存在的指令有一些限制。特別是,至少在目前,替換和排除指令是不允許的。從長遠來看,一旦新的go install program@version在足夠多的用例中執行良好,我們計畫讓go get停止安裝命令二進位制檔案。詳情請參見issue 43684。

您是否曾經在module版本準備好之前不小心發布過?或者您是否在版本發布後就發現了乙個需要快速修復的問題?發布的版本中的錯誤是很難糾正的。為了保持module構建的確定性,乙個版本在發布後不能被修改。即使你刪除或更改了版本標籤,proxy.golang.org和其他**可能已經有了原始版本的快取。

例如,假設乙個流行庫example.com/lib的作者發布了v1.0.5,然後發現了乙個新的安全問題。他們可以在他們的go.mod檔案中新增如下指令。

// remote-triggered crash in package foo. see cve-2021-01234.

retract v1.0.5

接下來,作者可以標記並推送v1.0.6版本,即新的最高版本。在這之後,已經依賴v1.0.5的使用者在檢查更新或公升級依賴的軟體包時,就會被通知版本撤回。通知資訊可能會包含來自retract指令上方注釋的文字。

go get example.com/lib@latest關於互動式的、基於瀏覽器的使用指南,請檢視play-with-go.dev上的retract module versions。可以檢視retract指令文件以了解語法細節。

go 1.16引入了乙個新的配置變數govcs,讓使用者可以指定哪些module可以使用特定的版本控制工具。govcs接受乙個以逗號分隔的pattern:vcslist規則列表。pattern是乙個path.match模式,匹配乙個module路徑的乙個或多個字首元素。特殊模式public和private匹配公共和私有module(private被定義為由goprivate中的模式匹配的module;public是其他所有module)。vcslist是乙個以管道符分隔的允許的版本控制命令列表,或關鍵字alloff

例如

govcs=github.com:git,evil.com:off,*:git|hg
如果沒有設定govcs,或者乙個module不符合任何模式,go命令就會使用這個預設值:公共module允許使用githg,私有module允許使用所有工具。只允許gitmercurial的理由是,這兩個系統作為不受信任的伺服器的客戶端執行的問題最受關注。相比之下,bazaarfossilsubversion主要是在受信任的、經過認證的環境中使用,作為攻擊面的審查程度不高。也就是說,預設的設定是

govcs=public:git|hg,private:all
更多細節請參見使用govcs控制版本管理工具

go中defer的乙個隱藏功能

在開始使用go進行編碼時,defer是要關注的乙個很重要的特性。它非常簡單 在任何函式中,給其他函式的呼叫加上字首defer以確保該函式在外部函式退出之前立即執行,即使外部函式出現異常被中斷,該延遲函式也將執行。但是,你還可以使用defer在任何函式開始後和結束前執行配對的 這個隱藏的功能在網上的教...

shell中,合成多個命令功能,建立新命令

用shell時,有的命令用著很不舒服,可以自己修改shell命令的功能組合,建立新的命令。比如,我想把cd命令和ls命令合成到一起重新命名為cd,即每次執行cd命令時,順便把目錄中的內容列印出來。1 首先以root許可權進入 usr bin目錄,在該目錄下編寫指令碼命名為cl.sh,內容如下 bin...

MySQL 8 中新的複製功能

mysql 8 中新的複製功能使得操作更加方便,並幫助使用者更好地觀察複製過程中內部發生的情況。使用 mysql 5.7.17 獲取 mysql 組複製外掛程式是一項巨大的工作。組複製是乙個新的外掛程式,通過使用組通訊和狀態機複製,為使用者提供了一些不錯的複製屬性。這使得系統能夠免受 腦裂 情況影響...