日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
怎么知道某個(gè)API是在哪個(gè)Go版本添加的?這個(gè)功能如何實(shí)現(xiàn)的

 大家好,我是站長 polarisxu。

創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供克東網(wǎng)站建設(shè)、克東做網(wǎng)站、克東網(wǎng)站設(shè)計(jì)、克東網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、克東企業(yè)網(wǎng)站模板建站服務(wù),10年克東做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

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

 
 
 
 
  1. package main 
  2.  
  3. import ( 
  4.  "fmt" 
  5.   "strings" 
  6.  
  7. func main() { 
  8.   var b strings.Builder 
  9.   b.WriteString("polarisxu") 
  10.   fmt.Println(b.Cap()) 

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

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

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

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

01 常見的兩種方式

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

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

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

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

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

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

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

 
 
 
 
  1. // A Builder is used to efficiently build a string using Write methods. 
  2. // It minimizes memory copying. The zero value is ready to use. 
  3. // Do not copy a non-zero Builder. 
  4. type Builder struct { 
  5.  addr *Builder // of receiver, to detect copies by value 
  6.  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,然后就能找到如下的代碼:

 
 
 
 
  1. // InitVersionInfo parses the $GOROOT/api/go*.txt API definition files to discover 
  2. // which API features were added in which Go releases. 
  3. func (c *Corpus) InitVersionInfo() { 
  4.  var err error 
  5.  c.pkgAPIInfo, err = parsePackageAPIInfo() 
  6.  if err != nil { 
  7.   // TODO: consider making this fatal, after the Go 1.11 cycle. 
  8.   log.Printf("godoc: error parsing API version files: %v", err) 
  9.  } 
  10.  
  11. func parsePackageAPIInfo() (apiVersions, error) { 
  12.  var apiGlob string 
  13.  if os.Getenv("GOROOT") == "" { 
  14.   apiGlob = filepath.Join(build.Default.GOROOT, "api", "go*.txt") 
  15.  } else { 
  16.   apiGlob = filepath.Join(os.Getenv("GOROOT"), "api", "go*.txt") 
  17.  } 
  18.  
  19.  files, err := filepath.Glob(apiGlob) 
  20.  if err != nil { 
  21.   return nil, err 
  22.  } 
  23.  
  24.  vp := new(versionParser) 
  25.  for _, f := range files { 
  26.   if err := vp.parseFile(f); err != nil { 
  27.    return nil, err 
  28.   } 
  29.  } 
  30.  return vp.res, nil 

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

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

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

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

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

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

 
 
 
 
  1. // Initialize the version info before readTemplates, which saves 
  2. // the map value in a method value. 
  3. 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

本文轉(zhuǎn)載自微信公眾號(hào)「polarisxu」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系polarisxu公眾號(hào)。


當(dāng)前標(biāo)題:怎么知道某個(gè)API是在哪個(gè)Go版本添加的?這個(gè)功能如何實(shí)現(xiàn)的
標(biāo)題鏈接:http://www.5511xx.com/article/cdiihch.html