<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>

          標(biāo)準(zhǔn)庫(kù) API 從哪個(gè)版本開始?顯示的版本號(hào)如何實(shí)現(xiàn)的

          共 3628字,需瀏覽 8分鐘

           ·

          2021-02-09 06:36

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

          因?yàn)?Go 的兼容性做的很好,很多人不太關(guān)心 Go 的具體版本。然而有時(shí)候可能會(huì)涉及到版本的問題,比如你想使用 strings.Builder,Go 版本就必須 >= 1.10,但以下代碼在 Go1.10 卻編譯不通過。

          package?main

          import?(
          ?"fmt"
          ??"strings"
          )

          func?main()?{
          ??var?b?strings.Builder
          ??b.WriteString("polarisxu")
          ??fmt.Println(b.Cap())
          }

          編譯會(huì)報(bào)錯(cuò):

          $?go?version
          go?version?go1.10.8?darwin/amd64
          $?go?run?main.go
          #?command-line-arguments
          ./main.go:11:15:?b.Cap?undefined?(type?strings.Builder?has?no?field?or?method?Cap)

          提示 strings.Builder 類型沒有 Cap 字段或方法。

          所以,你知道標(biāo)準(zhǔn)庫(kù)中哪個(gè) API 是什么版本引入的嗎?或者更實(shí)際的是,我當(dāng)前的版本是否能使用某個(gè) API。

          01 常見的兩種方式

          在 Go 官網(wǎng)有最新穩(wěn)定版本的標(biāo)準(zhǔn)庫(kù)文檔。從 Go1.11 版本開始,在標(biāo)準(zhǔn)庫(kù)中,每個(gè)類型、函數(shù)或方法有加入的版本信息,如果沒有,表示 Go1.0 就有了,具體 issue 見:https://github.com/golang/go/issues/5778。但目前常量和變量沒有版本信息,具體 issue 見:https://github.com/golang/go/issues/29204。

          第二種方法,不是看具體某個(gè) API 對(duì)應(yīng)的版本,而是至少知曉,你當(dāng)前使用的 Go 版本有沒有某個(gè) API,這就是 pkg.go.dev,具體通過這個(gè)網(wǎng)站 https://pkg.go.dev/std?tab=versions 選擇你對(duì)應(yīng)的版本,然后查找是否有對(duì)應(yīng)的 API。

          當(dāng)然了,你使用 GoLand 之類的編輯器,某個(gè) API 是否有,它會(huì)自動(dòng)提示。

          02 標(biāo)準(zhǔn)庫(kù)顯示版本是如何實(shí)現(xiàn)的

          保持好奇心很重要,這是求知的動(dòng)力之一。看到官網(wǎng)標(biāo)準(zhǔn)庫(kù)顯示了版本信息,我就想看看它是怎么實(shí)現(xiàn)的。

          怎么查找實(shí)現(xiàn)的代碼?

          我的第一反應(yīng)是看標(biāo)準(zhǔn)庫(kù)注釋里有沒有寫。

          //?A?Builder?is?used?to?efficiently?build?a?string?using?Write?methods.
          //?It?minimizes?memory?copying.?The?zero?value?is?ready?to?use.
          //?Do?not?copy?a?non-zero?Builder.
          type?Builder?struct?{
          ?addr?*Builder?//?of?receiver,?to?detect?copies?by?value
          ?buf??[]byte
          }

          沒有看到任何版本相關(guān)信息。這時(shí)你會(huì)如何查找?

          我的方式是這樣的。

          1)在頁面審查元素,看到 1.10 節(jié)點(diǎn)。

          2)Go 官網(wǎng)源碼在這里:https://github.com/golang/website,在該源碼中搜索 Added in,找到了 package.html 模板文件。

          3)上圖中, $since 變量代表了 Go 版本,而它是通過 since 函數(shù)得到的:`{{.PDoc.ImportPath}}`,很顯然這是一個(gè)自定義模板函數(shù),因此查找它。website 項(xiàng)目沒有找到,因此到 tools[1] 項(xiàng)目去找:因?yàn)?godoc 在這個(gè)項(xiàng)目中。

          通過這個(gè)可以找到 sinceVersionFunc 所在文件:versions.go,然后就能找到如下的代碼:

          //?InitVersionInfo?parses?the?$GOROOT/api/go*.txt?API?definition?files?to?discover
          //?which?API?features?were?added?in?which?Go?releases.
          func?(c?*Corpus)?InitVersionInfo()?{
          ?var?err?error
          ?c.pkgAPIInfo,?err?=?parsePackageAPIInfo()
          ?if?err?!=?nil?{
          ??//?TODO:?consider?making?this?fatal,?after?the?Go?1.11?cycle.
          ??log.Printf("godoc:?error?parsing?API?version?files:?%v",?err)
          ?}
          }

          func?parsePackageAPIInfo()?(apiVersions,?error)?{
          ?var?apiGlob?string
          ?if?os.Getenv("GOROOT")?==?""?{
          ??apiGlob?=?filepath.Join(build.Default.GOROOT,?"api",?"go*.txt")
          ?}?else?{
          ??apiGlob?=?filepath.Join(os.Getenv("GOROOT"),?"api",?"go*.txt")
          ?}

          ?files,?err?:=?filepath.Glob(apiGlob)
          ?if?err?!=?nil?{
          ??return?nil,?err
          ?}

          ?vp?:=?new(versionParser)
          ?for?_,?f?:=?range?files?{
          ??if?err?:=?vp.parseFile(f);?err?!=?nil?{
          ???return?nil,?err
          ??}
          ?}
          ?return?vp.res,?nil
          }

          通過以上代碼可以看出來版本信息是通過讀取 GOROOT 下 api/go*.txt 文件獲取的。

          api 目錄下的這些文件維護(hù)了每個(gè)版本新增的內(nèi)容。

          最終從這些文件中讀取的內(nèi)容會(huì)用以下的類型表示:

          //?pkgAPIVersions?contains?information?about?which?version?of?Go?added
          //?certain?package?symbols.
          //
          //?Only?things?added?after?Go1?are?tracked.?Version?strings?are?of?the
          //?form?"1.1",?"1.2",?etc.
          type?pkgAPIVersions?struct?{
          ?typeSince???map[string]string????????????//?"Server"?->?"1.7"
          ?methodSince?map[string]map[string]string?//?"*Server"?->"Shutdown"->1.8
          ?funcSince???map[string]string????????????//?"NewServer"?->?"1.7"
          ?fieldSince??map[string]map[string]string?//?"ClientTrace"?->?"Got1xxResponse"?->?"1.11"
          }

          這里有類型、方法、函數(shù)和(類型)字段,但沒有變量和常量,這也就是說變量和常量的版本號(hào)顯示還未實(shí)現(xiàn)。

          最后,在 website 項(xiàng)目的 main 函數(shù)中有這么一句:

          //?Initialize?the?version?info?before?readTemplates,?which?saves
          //?the?map?value?in?a?method?value.
          corpus.InitVersionInfo()

          用于初始化版本信息。

          03 總結(jié)

          希望你平時(shí)生活、學(xué)習(xí)和工作過程中,能多一些好奇。本文是一個(gè)引子,內(nèi)容不太重要,過程希望能夠?qū)δ阌兴鶈l(fā)。當(dāng)然,如果你計(jì)劃學(xué)習(xí)學(xué)習(xí) Go 語言官網(wǎng)的實(shí)現(xiàn),也許本文的幫助會(huì)更大。

          參考資料

          [1]

          tools: https://github.com/golang/tools




          往期推薦


          福利

          我為大家整理了一份從入門到進(jìn)階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門看什么,進(jìn)階看什么。關(guān)注公眾號(hào) 「polarisxu」,回復(fù)?ebook?獲取;還可以回復(fù)「進(jìn)群」,和數(shù)萬 Gopher 交流學(xué)習(xí)。

          瀏覽 51
          點(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>
                  无码嫩逼电影 | gg在线精品视频观看 | 看毛片网站 | 围产精品久久久久久久黄无码 | 欧美黑吊大战白妞欧美大片 |