<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go 1.17 新特性:Module 有哪些變化?

          共 4998字,需瀏覽 10分鐘

           ·

          2021-08-23 09:45

          閱讀本文大概需要 5 分鐘。

          大家好,我是 polarisxu。

          自從 Go1.11 增加 Go Module 以來,每個(gè)版本都在不斷改進(jìn) Module。Go1.17 也不例外。這次最主要的變化有兩點(diǎn):

          • Module graph pruning:Module 依賴圖修剪
          • Lazy Loading:Module 延遲加載

          此外還有 Deprecated 注釋等。本文就一起探究下這些新變化,因?yàn)橛腥藳]看懂,不知道這些變化是什么意思。

          01 Module 依賴圖修剪

          要搞懂這個(gè)知識(shí)點(diǎn),需要對(duì)比 1.17 之前的情況。

          注意,這個(gè)變化并不會(huì)影響 go mod 的任何使用

          為了方便演示,我們構(gòu)建一個(gè)這樣的例子。

          有四個(gè)模塊:主模塊(studymod)和 a、b、c 三個(gè)模塊,如下圖:

          module studymod 是我們的項(xiàng)目,它依賴模塊 a 中的 x 包,而 x 包依賴模塊 b,同時(shí) a 包中的 y 包依賴模塊 c。

          很顯然,對(duì)我們的項(xiàng)目 studymod 來說,模塊 c 的代碼根本沒用上。Go 1.17 對(duì) module 的改進(jìn)主要就是在這種沒用上的模塊上。

          基于 Go1.16

          假定在 $HOME 下創(chuàng)建一個(gè)新目錄 gomod116,構(gòu)建如下目錄結(jié)構(gòu):

          [xuxinhua@/Users/xuxinhua/gomod116]
          $ tree -L 3
          .
          ├── a
          │   ├── x
          │   │   └── x.go // 包含正確的包定義和 import
          │   └── y
          │       └── y.go
          ├── b
          │   └── b.go
          ├── c
          │   └── c.go
          └── studymod.go

          在 Go 文件中只是簡(jiǎn)單的定義包和 import。幾個(gè) go 文件的內(nèi)容分別如下:

          // x.go
          package x

          import _ "b"

          // y.go
          package y

          import _ "c"

          // b.go
          package b

          // c.go
          package c

          // studymod.go
          package studymod

          import _ "a/x"

          進(jìn)入 gomod116 目錄,將 Go 版本切換到 Go1.16.x(多版本發(fā)揮作用了,多版本問題,可以看看這篇文章:終于找到了一款我喜歡的安裝和管理 Go 版本的工具),然后執(zhí)行下列命令:

          $ go mod init studymod
          cd a
          $ go mod init a
          cd ../b
          $ go mod init b
          cd ../c
          $ go mod init c

          因?yàn)槟K a 依賴模塊 b 和 c,往 a/go.mod 增加如下代碼:

          module a

          go 1.16

          require (
              b v0.1.0
              c v0.1.0
          )

          在 gomod116 根目錄的 go.mod 增加如下代碼:

          module studymod

          go 1.16

          require a v0.1.0

          replace (
                  a v0.1.0 => ./a
                  b v0.1.0 => ./b
                  c v0.1.0 => ./c
          )

          因?yàn)?studymod 只直接依賴模塊 a。replace 部分可以忽略,只是為了本地能夠正常引入模塊。

          此時(shí),在 gomod116 目錄下執(zhí)行 go build,如果不報(bào)錯(cuò),表示一切正常,我們可以執(zhí)行如下命令看到依賴關(guān)系:

          $ go mod graph
          studymod [email protected]
          [email protected] [email protected]
          [email protected] [email protected]

          studymod 依賴 a,a 依賴 b 和 c。

          但我們知道,studymod 模塊實(shí)際根本不需要模塊 c,因此,我們嘗試在 studymod 模塊中刪除模塊 c 的引用,即刪除 go.mod 中 replace 部分的 c v0.1.0 => ./c,再次執(zhí)行 go build:

          $ go build
          go: [email protected] requires
           [email protected]: missing go.sum entry; to add it:
           go mod download c

          可見模塊 c 不能少。(驗(yàn)證后,記得將 go.mod 恢復(fù)原樣)

          基于 Go1.17

          現(xiàn)在我們基于 Go1.17 做類似的驗(yàn)證,將 Go 切到 1.17,執(zhí)行如下命令,將 gomod116 拷貝一份:

          $ cp -rf gomod116 gomod117

          然后進(jìn)入 gomod117 目錄,將 go.mod 的 版本由 1.16 改為 1.17:

          module studymodgo 1.17require a v0.1.0replace (    a v0.1.0 => ./a    b v0.1.0 => ./b    c v0.1.0 => ./c)

          接著執(zhí)行 go mod tidy,發(fā)現(xiàn) go.mod 變成這樣:

          module studymodgo 1.17require a v0.1.0require b v0.1.0 // indirectreplace (        a v0.1.0 => ./a        b v0.1.0 => ./b        c v0.1.0 => ./c)

          多了一行 require,記錄了 module studymod 的間接依賴:module [email protected]。執(zhí)行 go build 一切正常。

          跟 Go1.16 一樣,刪除掉 c v0.1.0 => ./c 這行,再次執(zhí)行 go build,依然正常。這就是依賴圖裁剪,再看依賴關(guān)系,跟 Go1.16 是不一樣的。

          $ go mod graphstudymod [email protected] [email protected]@v0.1.0 [email protected]@v0.1.0 [email protected]

          這么做的優(yōu)劣

          這么做是基于社區(qū)的反饋,有興趣的可以看看這個(gè)提案:Proposal: Lazy Module Loading,這也是合理的,畢竟沒有用到的代碼為什么一定需要呢?

          此外,裁剪后,go.mod 中會(huì)包含入更多的依賴項(xiàng)(完整的依賴列表),新包含的依賴項(xiàng)單獨(dú)放在一個(gè) require 下。可以通過 https://github.com/studygolang/studygolang 試驗(yàn)下。下載該代碼后,執(zhí)行如下命令:

          $ go mod tidy -go=1.17

          diff 后,在原來的基礎(chǔ)上多出了如下的 require:

          有點(diǎn)類似其他語言中 xxx.lock 文件的感覺了。

          當(dāng)然,這種方式后,go.mod 的文件會(huì)更大,這也是該方式的一個(gè)相對(duì)劣勢(shì)。

          02 延遲加載(lazy Loading)

          理解了上面依賴圖的裁剪,延遲加載就一句話:那些根本沒有用上的模塊(比如上面例子中的模塊 c),Go 1.17 后,Go 命令不會(huì)去讀取其 go.mod 文件。如果之后需要了,再去加載。

          03 Deprecated 注釋

          Go1.17 go.mod 中支持 Deprecated 注釋,用來標(biāo)明該模塊廢棄了。

          // Deprecated: use example.com/mod/v2 instead.module example.com/mod

          對(duì)于那些使用了被廢棄的 module 的 go 項(xiàng)目,go list、go get 命令都會(huì)給出 warning。

          看過我這篇文章:《從 go-chi 框架撤回所有主版本聊 Go1.16 的新特性》 的朋友,可能會(huì)有疑問,撤回和廢棄有何不同,如何分別使用?這里稍微總結(jié)下:

          撤回的使用場(chǎng)景

          • 發(fā)現(xiàn)了一個(gè)嚴(yán)重的安全漏洞;
          • 發(fā)現(xiàn)了嚴(yán)重的不兼容性或 bug;
          • 這個(gè)版本是偶然發(fā)布的,或是過早發(fā)布了;

          而 Deprecated 是用來作廢整個(gè) module 的,也就是說,不能廢棄某個(gè) minor 或 patch 版本。Deprecated 更多用來提示使用者升級(jí)到更新的 major 版本,比如要廢棄 v1,希望大家升級(jí)到 v2,就應(yīng)該使用 Deprecated。

          04 總結(jié)

          還有其他一些小的變動(dòng),這里不一一列舉。提醒下大家,從 Go1.16 版本開始,下載安裝 Go 二進(jìn)制程序,不再使用 go get,而是 go install,go get 只用來下載普通包。

          因?yàn)?module 越來越完善,官方針對(duì) module 也有更完整的文檔:https://docs.studygolang.com/ref/mod。




          往期推薦


          我是 polarisxu,北大碩士畢業(yè),曾在 360 等知名互聯(lián)網(wǎng)公司工作,10多年技術(shù)研發(fā)與架構(gòu)經(jīng)驗(yàn)!2012 年接觸 Go 語言并創(chuàng)建了 Go 語言中文網(wǎng)!著有《Go語言編程之旅》、開源圖書《Go語言標(biāo)準(zhǔn)庫》等。


          堅(jiān)持輸出技術(shù)(包括 Go、Rust 等技術(shù))、職場(chǎng)心得和創(chuàng)業(yè)感悟!歡迎關(guān)注「polarisxu」一起成長(zhǎng)!也歡迎加我微信好友交流:gopherstudio


          瀏覽 61
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91麻豆精品无码一区二区三区 | 性情网站 | 噜噜噜影院 | 欧美成人做爱 | 亚洲欧美一级电影 |