精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

迷惑了,Go len() 是怎么計(jì)算出來(lái)的?

開(kāi)發(fā) 后端
最近看到了一個(gè)很有意思的話(huà)題,我們平時(shí)常常會(huì)用 Go 的內(nèi)置函數(shù) len 去獲取各種 map、slice 的長(zhǎng)度,那他是怎么實(shí)現(xiàn)的呢?

[[416772]]

本文轉(zhuǎn)載自微信公眾號(hào)「腦子進(jìn)煎魚(yú)了」,作者陳煎魚(yú)。轉(zhuǎn)載本文請(qǐng)聯(lián)系腦子進(jìn)煎魚(yú)了公眾號(hào)。

大家好,我是煎魚(yú)。

最近看到了一個(gè)很有意思的話(huà)題,我們平時(shí)常常會(huì)用 Go 的內(nèi)置函數(shù) len 去獲取各種 map、slice 的長(zhǎng)度,那他是怎么實(shí)現(xiàn)的呢?

正當(dāng)我想去看看 len 的具體實(shí)現(xiàn)時(shí),一展身手,卻發(fā)現(xiàn)竟然是個(gè)空方法:

  1. func len(v Type) int 

看注解也沒(méi)有 link 到其他 runtime 函數(shù),那么 len 函數(shù)是如何被調(diào)用的呢?

先前也做了一些筆記,在此分享給大家,共同進(jìn)步。

謎底

今天就由煎魚(yú)帶大家一同解開(kāi)這個(gè)謎底。既然是謎底,那就一開(kāi)始就揭開(kāi)。

其實(shí) Go 語(yǔ)言中并沒(méi)有 len 函數(shù)的具體實(shí)現(xiàn)代碼,他其實(shí)是 Go 編譯器的 "魔法" ,不是實(shí)際的函數(shù)調(diào)用。

接下來(lái)將展開(kāi)這部分,我們可以更深入地了解 Go 編譯器的內(nèi)部工作原理。

編譯器

在 Go 編譯器編譯時(shí)會(huì)解析命令行參數(shù)中指定的標(biāo)志和 Go 源文件,對(duì)解析后的 Go 包進(jìn)行類(lèi)型檢查,將函數(shù)編譯為機(jī)器代碼。代碼,最后將編譯后的包定義寫(xiě)到磁盤(pán)上。

內(nèi)部定義基本類(lèi)型、內(nèi)置函數(shù)和操作函數(shù)的階段是在 types/universe.go 當(dāng)中。同時(shí)會(huì)進(jìn)行內(nèi)置函數(shù)和具體的操作符匹配,可以明確知道內(nèi)置函數(shù) len 對(duì)應(yīng)的是 OLEN:

  1. var builtinFuncs = [...]struct { 
  2.  name string 
  3.  op   Op 
  4. }{ 
  5.  {"append", OAPPEND}, 
  6.  {"cap", OCAP}, 
  7.  {"close", OCLOSE}, 
  8.  {"complex", OCOMPLEX}, 
  9.  {"copy", OCOPY}, 
  10.  {"delete", ODELETE}, 
  11.  {"imag", OIMAG}, 
  12.  {"len", OLEN}, 
  13.  ... 

在編譯時(shí),上分為五個(gè)階段進(jìn)行類(lèi)型檢查:

  • 第一階段:常量、類(lèi)型、以及函數(shù)的名稱(chēng)和類(lèi)型。
  • 第二階段:變量賦值、接口賦值、別名聲明。
  • 第三階段:類(lèi)型檢查函數(shù)體。
  • 第四階段:檢查外部聲明。
  • 第五階段:檢查類(lèi)型的地圖鍵,未使用的導(dǎo)入。

如果最后一個(gè)類(lèi)型檢查階段遇到 len 函數(shù),就會(huì)轉(zhuǎn)換為 UnaryExpr 類(lèi)型,一個(gè) UnaryExpr 節(jié)點(diǎn)代表一個(gè)單數(shù)表達(dá)式,也最終就是不會(huì)成為函數(shù)調(diào)用:

  1. func typecheck1(n ir.Node, top int) ir.Node { 
  2.  if n, ok := n.(*ir.Name); ok { 
  3.   typecheckdef(n) 
  4.  } 
  5.  
  6.  switch n.Op() { 
  7.  ... 
  8.  case ir.OCAP, ir.OLEN: 
  9.   n := n.(*ir.UnaryExpr) 
  10.   return tcLenCap(n) 
  11.  } 

在調(diào)用 *ir.UnaryExpr 轉(zhuǎn)換完畢后,會(huì)調(diào)用 tcLenCap,也就是 typecheck,使用 okforlen 數(shù)組來(lái)驗(yàn)證參數(shù)的合法性或發(fā)出相關(guān)錯(cuò)誤信息:

  1. func tcLenCap(n *ir.UnaryExpr) ir.Node { 
  2.  n.X = Expr(n.X) 
  3.  n.X = DefaultLit(n.X, nil) 
  4.  n.X = implicitstar(n.X) 
  5.  ... 
  6.  var ok bool 
  7.  if n.Op() == ir.OLEN { 
  8.   ok = okforlen[t.Kind()] 
  9.  } else { 
  10.   ok = okforcap[t.Kind()] 
  11.  } 
  12.    
  13.  ... 
  14.  n.SetType(types.Types[types.TINT]) 
  15.  return n 

經(jīng)歷過(guò)上面的步驟后在對(duì)所有內(nèi)容進(jìn)行類(lèi)型檢查后,所有函數(shù)都將排隊(duì)等待編譯:

  1. base.Timer.Start("be""compilefuncs"
  2. fcount := int64(0) 
  3. for i := 0; i < len(typecheck.Target.Decls); i++ { 
  4.  if fn, ok := typecheck.Target.Decls[i].(*ir.Func); ok { 
  5.   enqueueFunc(fn) 
  6.   fcount++ 
  7.  } 
  8. base.Timer.AddEvent(fcount, "funcs"
  9.  
  10. compileFunctions() 

在經(jīng)過(guò)在 buildssa 和 genssa 之后,再深入幾層,就會(huì)將 AST 樹(shù)中的 len 表達(dá)式轉(zhuǎn)換為 SSA。接著我們就可以看到 Go 語(yǔ)言中的每種類(lèi)型的長(zhǎng)度是怎么獲取的。

這塊的處理對(duì)應(yīng) internal/ssagen/ssa.go 的 expr 方法,如下:

  1. case ir.OLEN, ir.OCAP: 
  2.  n := n.(*ir.UnaryExpr) 
  3.  switch { 
  4.  case n.X.Type().IsSlice(): 
  5.   op := ssa.OpSliceLen 
  6.   if n.Op() == ir.OCAP { 
  7.    op = ssa.OpSliceCap 
  8.   } 
  9.   return s.newValue1(op, types.Types[types.TINT], s.expr(n.X)) 
  10.  case n.X.Type().IsString(): // string; not reachable for OCAP 
  11.   return s.newValue1(ssa.OpStringLen, types.Types[types.TINT], s.expr(n.X)) 
  12.  case n.X.Type().IsMap(), n.X.Type().IsChan(): 
  13.   return s.referenceTypeBuiltin(n, s.expr(n.X)) 
  14.  default: // array 
  15.   return s.constInt(types.Types[types.TINT], n.X.Type().NumElem()) 
  16.  } 

若是數(shù)組(array)類(lèi)型,則會(huì)調(diào)用 NumElem 方法來(lái)獲取長(zhǎng)度值:

  1. type Array struct { 
  2.  Elem  *Type  
  3.  Bound int64  
  4.  
  5. func (t *Type) NumElem() int64 { 
  6.  t.wantEtype(TARRAY) 
  7.  return t.Extra.(*Array).Bound 

若是字典(map)類(lèi)型或通道(channel),將會(huì)調(diào)用 referenceTypeBuiltin 方法:

  1. func (s *state) referenceTypeBuiltin(n *ir.UnaryExpr, x *ssa.Value) *ssa.Value { 
  2.  lenType := n.Type() 
  3.  nilValue := s.constNil(types.Types[types.TUINTPTR]) 
  4.  cmp := s.newValue2(ssa.OpEqPtr, types.Types[types.TBOOL], x, nilValue) 
  5.  b := s.endBlock() 
  6.  b.Kind = ssa.BlockIf 
  7.  b.SetControl(cmp) 
  8.  b.Likely = ssa.BranchUnlikely 
  9.  
  10.  bThen := s.f.NewBlock(ssa.BlockPlain) 
  11.  bElse := s.f.NewBlock(ssa.BlockPlain) 
  12.  bAfter := s.f.NewBlock(ssa.BlockPlain) 
  13.  ... 
  14.  switch n.Op() { 
  15.  case ir.OLEN: 
  16.   s.vars[n] = s.load(lenType, x) 
  17.  ... 
  18.  return s.variable(n, lenType) 

該函數(shù)的作用是是獲取 map 或chan 的內(nèi)存地址,并以零偏移量引用其結(jié)構(gòu)布局,就像 unsafe.Pointer(uintptr(unsafe.Pointer(s)) 一樣,返回第一個(gè)字面字段的值。

那為什么要獲取結(jié)構(gòu)體的第一個(gè)字段的值呢,應(yīng)該是和 map 和 chan 的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)有關(guān):

  1. type hmap struct { 
  2.  count     int  
  3.   ... 
  4.  
  5. type hchan struct { 
  6.  qcount   uint     
  7.  ... 

是因?yàn)?map 和 chan 的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)的第一個(gè)字段就表示長(zhǎng)度,自然也就通過(guò)計(jì)算偏移值來(lái)獲取了。

其他的數(shù)據(jù)類(lèi)型,大家可以繼續(xù)深入代碼,再細(xì)看就好了。主要還是枚舉多同類(lèi)的數(shù)據(jù)類(lèi)型,接著調(diào)用相應(yīng)的方法。

總結(jié)

每次我們看到內(nèi)置函數(shù)時(shí),總會(huì)下意識(shí)的以為是在 runtime 內(nèi)實(shí)現(xiàn)的。看不到 runtime 內(nèi)的實(shí)現(xiàn)方法,又會(huì)以為是通過(guò)注解 link 的方式來(lái)解決的。

 

但需要注意,其實(shí)還有像 len 內(nèi)置函數(shù)這種直接編譯器轉(zhuǎn)換的,這也是一種不錯(cuò)的優(yōu)化方式。

 

責(zé)任編輯:武曉燕 來(lái)源: 腦子進(jìn)煎魚(yú)了
相關(guān)推薦

2022-02-24 07:56:27

Linux系統(tǒng)ELF

2024-04-15 00:00:00

首屏優(yōu)化元素

2015-06-25 10:57:15

推薦系統(tǒng)老婆算出來(lái)

2022-07-14 08:22:48

Computedvue3

2009-11-06 13:54:09

Visual Stud

2021-03-01 10:38:13

深度學(xué)習(xí)編程人工智能

2017-07-25 18:36:00

機(jī)器學(xué)習(xí)WOT票房

2023-11-08 08:09:36

幾何算法解析幾何

2018-12-12 11:11:20

系統(tǒng)可靠性可用性

2023-05-08 00:01:29

數(shù)據(jù)分析指標(biāo)標(biāo)簽

2024-12-26 11:49:14

2009-09-10 16:22:48

LINQ建立數(shù)據(jù)報(bào)表

2020-03-16 10:42:23

大數(shù)據(jù)IT工具

2016-10-17 16:13:32

云計(jì)算

2025-07-01 01:55:00

Redis集群模式

2012-04-25 22:58:36

2011-08-24 13:32:56

CREATE TABL中文man

2022-10-12 00:07:25

加密貨幣區(qū)塊鏈比特幣

2020-03-02 15:14:53

手機(jī)計(jì)算步數(shù)

2018-10-29 11:25:38

云計(jì)算行業(yè)科技
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

国产色视频在线| 久久不见久久见免费视频7| www.桃色.com| 亚洲美女性视频| 狠狠色狠狠色综合婷婷tag| 国产又粗又长免费视频| 精品国产欧美一区二区五十路| 久久视频在线| 日本熟妇成熟毛茸茸| 国产精品久久久久久久久久免费| 久久91精品久久久久久秒播| 亚洲国产精品视频在线| 久久伊人资源站| 国产精品乱码一区二区三区软件| 新版中文在线官网| 日韩精品你懂的| 亚洲国产福利在线| 亚洲精品网址| 无码人妻精品一区二区三区9厂 | av电影在线地址| 一路向西2在线观看| 亚洲精品动漫100p| 欧美精品1区| 中文字幕乱码视频| 久久精品美女| 亚洲国产另类精品专区| 在线观看欧美| 91av在线免费| 久久久久久av| 国产乱妇无码大片在线观看| 18在线观看的| 乱码一区二区三区| 欧美尺度大的性做爰视频| 卡一卡二国产精品| 免费在线观看av| 国产精品白丝jk白祙| 国产精品456| 又爽又大又黄a级毛片在线视频| 欧美成人三级在线视频| 精品欧美久久久| 欧美日韩ab| 色视频精品视频在线观看| 北条麻妃av高潮尖叫在线观看| 国产一区二区美女视频| 亚洲一区二区三区四区五区午夜| 亚洲 欧美 自拍偷拍| 北条麻妃69av| 色婷婷久久av| 福利一区福利二区| 欧美最新精品| 亚洲色图综合区| 97自拍视频| 91黄色免费网站| 国语精品一区| 天堂资源在线中文| 亚洲人人夜夜澡人人爽| 国产精品一区二区3区| 一区二区三区在线免费视频| 成人91在线| 亚洲AV无码精品国产| 精品国产免费av| 久久激情视频久久| 亚洲国产岛国毛片在线| 奇米影视777在线欧美电影观看| 日韩在线播放中文字幕| 996这里只有精品| 爱福利视频一区| 成人视屏免费看| 久久国产精品美女| 亚洲图片欧美在线| 国产96在线 | 亚洲| 久久国内精品一国内精品| 中文字幕一区二区三区精华液 | 国模无码大尺度一区二区三区| 成人免费无遮挡| 国产无套在线观看| 黄色一级片av| 久久久久久综合网天天| 亚洲视频网在线直播| 欧美xxxxx视频| 99中文字幕一区| 青青操在线播放| 亚洲欧洲一区二区福利| 亚洲曰韩产成在线| 国产一区二区精品久| 天天干视频在线| 一级黄色电影片| 国外成人免费视频| 亚洲图片欧美午夜| 自拍偷拍欧美精品| 亚洲人www| 日韩制服一区| 亚洲自拍偷拍另类| 青青草精品在线| 国模一区二区三区私拍视频| 亚洲色图校园春色| 亚洲精品国产a| 亚洲一级网站| 免费看av不卡| 国产一区二区女内射| 在线免费黄色网| 欧美三级电影在线播放| 日韩在线视频免费观看高清中文| 一区二区三区精密机械公司| 亚洲一区二区三区高清不卡| 亚洲黑人在线| 青青草免费在线| 午夜写真片福利电影网| 欧美爱爱视频免费看| 国产综合久久久久| 国产丝袜精品视频| 亚洲自拍另类综合| 久久99久久久久久久久久久| 农村少妇一区二区三区四区五区| 成人午夜福利视频| 人妻大战黑人白浆狂泄| 久艹在线免费观看| 97超碰在线播放| 欧美成aaa人片免费看| 欧美日韩成人在线| 国产欧美一区二区精品仙草咪| aa亚洲婷婷| 四虎影视精品| 中文字幕在线中文字幕在线中三区| 亚洲国产成人一区二区 | 毛片av在线播放| 91在线在线观看| 欧美精品福利视频| 亚洲成人三级在线| 日韩欧美亚洲一二三区| 国产亚洲欧美一区在线观看| 人禽交欧美网站| 亚洲精品网址| 国产精品毛片视频| yw.尤物在线精品视频| 成a人v在线播放| 国产精品一区二区免费视频| 中文字幕在线观看你懂的| 亚洲熟女一区二区| 日本视频精品一区| 亚洲精品视频观看| 精品一区二区三区在线视频| 久久精品青草| 亚洲啊v在线免费视频| 新版中文在线官网| 欧日韩在线视频| 中文字幕一区在线播放| 美女100%露胸无遮挡| 三级一区二区三区| 蜜臀精品一区二区| 日本一区二区三区视频在线播放| 91精品国产综合久久香蕉922| 久久国产精品久久久久| 亚洲欧美一区二区精品久久久 | 亚洲一区二区三区在线视频 | 激情亚洲小说| 密臀av在线播放| 美女国产在线| 精品亚洲成a人片在线观看| 亚洲一区二区激情| 久草视频在线资源| 国产精品成人69xxx免费视频| 99久久国产精| 精品熟女一区二区三区| 香蕉视频999| 黄色三级视频片| 熟女人妇 成熟妇女系列视频| 亚洲熟妇无码一区二区三区导航| 粉嫩av一区二区三区天美传媒| 亚洲国产精品一区二区第四页av| 国产一区免费在线观看| 波多野结衣成人在线| 国产精品网站视频| 国产日韩欧美另类| 亚洲最大的网站| 91久久极品少妇xxxxⅹ软件| 91精品久久久久久久久| 国产成一区二区| 国产情人节一区| 97超碰在线播放| 亚洲iv一区二区三区| 国产精品久久久久久久久久久久冷| 亚洲最大av在线| 国产精品亚洲综合| 欧美日韩电影一区二区三区| 日韩精品一区二区三区丰满| 欧美日韩系列| 一区二区三区四区久久| 97在线国产视频| 亚欧在线免费观看| 亚洲综合123| 黄色国产在线观看| 亚洲欧美另类日本| 久久精品人妻一区二区三区| 久久久久久久久久影院| 亚洲一卡二卡在线观看| 五月天婷婷在线观看| 日本三级视频在线播放| 2019中文字幕在线电影免费| 深夜av在线| 国产一区二区视频在线看| 在线观看视频一区二区三区| 日本电影一区二区| 国产亚洲网站| 国产伦精品一区二区三区视频青涩 | 翡翠波斯猫1977年美国| 久久国产精品久久| 国产欧美123| 国模私拍视频在线观看| 岛国av免费观看| 美国黄色特级片| 日本熟妇毛耸耸xxxxxx| jlzzjlzzjlzz亚洲人| 日本三级视频在线播放| 无遮挡爽大片在线观看视频 | 国产亚洲综合在线| 在线日韩一区二区| 日韩av在线最新| 欧美激情极品视频| 欧美—级高清免费播放| 91精品久久久久久久| 欧美日韩一区综合| 男的插女的下面视频| 亚洲视频在线不卡| 日韩黄色精品视频| 日韩在线无毛| 极品视频在线| 精品欧美午夜寂寞影院| 一区二区三区四区日韩| 国产xxx精品视频大全| 五月激情综合婷婷| 精品亚洲一区二区三区在线观看 | 一区二区在线播放视频| 在线观看日本中文字幕| 在线观看中文字幕码| 91小视频xxxx网站在线| 麻豆精品99| 奇米888四色在线精品| 中文字幕乱码一区二区免费| 777a∨成人精品桃花网| 97精品在线视频| 尤物一区二区三区| 在线播放第一页| 精品91久久久| 中国av在线播放| 成人看的羞羞网站| 精品一区二区久久| 亚洲一区二区三区视频在线播放 | 亚洲一区 在线播放| 熟女俱乐部一区二区视频在线| 亚洲av综合一区| 青春草免费在线视频| 亚洲第一福利社区| 精品亚洲免费视频| 欧美精品自拍偷拍| 4438全国成人免费| 亚洲女人毛片| 亚洲色图欧美日韩| 亚洲成人77777| 国产一区一区| 日韩精品乱码免费| 性久久久久久久久久久久| 久久久精品电影| 亚洲日本精品| 日本一二三不卡视频| 日韩a级作爱片一二三区免费观看| 视频一区视频二区欧美| 精品一区二区在线播放| 欧美三区免费完整视频在线观看| 18性欧美xxxⅹ性满足| 日韩精品视频在线观看视频| 欧美三级 欧美一级| 国精产品一区| 亚洲一级黄色| 日韩欧美国产免费播放| 国产精品一区二区三区在线播放 | 国产99免费视频| 99久久伊人| 国产在线一区二区| 欧美刺激脚交jootjob| 亚洲一区亚洲二区亚洲三区| 91成人在线观看喷潮蘑菇| 韩国av免费在线| 久久99国内| 国产精品网站一区| 亚洲18私人小影院| 欧美s码亚洲码精品m码| 黄色片免费观看视频| 97久久中文字幕| 91免费在线视频观看| 最近更新的2019中文字幕| 亚洲蜜桃av| 青青草av在线播放| 国产欧美日韩电影| 2023国产精品自拍| 中文字幕精品在线视频| 免费在线观看亚洲视频| 中文区中文字幕免费看| 日韩最新av| 亚洲欧美一区二区三区国产精品| 911国产网站尤物在线观看| 亚洲国产精品三区| 国产女主播在线直播| 国产精品v亚洲精品v日韩精品| 日韩欧美亚洲成人| 99久久99久久精品国产片| 少妇无套高潮一二三区| 精品三级久久| 白白色 亚洲乱淫| 欧美国产在线电影| 五月天丁香社区| 欧美日韩经典丝袜| 狠狠色综合播放一区二区| 亚洲精品视频二区| 激情婷婷综合网| 最新97超碰在线| 日韩精彩视频在线观看| 永久免费看mv网站入口亚洲| 精品国产成人av在线免| 亚洲 小说区 图片区 都市| 亚洲国产日韩欧美一区二区三区| 日韩午夜激情av| 日韩欧美精品免费| 网站黄在线观看| 1024成人| 在线看日韩欧美| 欧美日韩一区二区三区69堂| 国产专区在线播放| 国产欧美日韩综合一区在线播放 | 国产裸体无遮挡| 婷婷综合亚洲| 日韩欧美一级在线播放| 欧美不卡在线播放| 男人的天堂在线| 日本欧美大码aⅴ在线播放| 亚洲女人天堂色在线7777| 亚洲小视频网站| 美女91在线| 亚洲国产精品自拍| 欧美一级淫片videoshd| 精品一区久久久久久| 亚洲国产精品成人无久久精品| 亚洲精品在线播放| 在线精品亚洲一区二区不卡| 中文字幕在线观看一区二区三区| 国产欧美第一页| 三级不卡在线观看| 欧美成人午夜激情在线| 国产精品三级在线观看无码| 国产精品视频一区二区三区| 色八戒一区二区三区| 日本一级黄视频| 欧美被日视频| 中文字幕不卡三区| 精品国产_亚洲人成在线| 国产美女永久免费| 九九精品视频在线看| 国产成人精品视频在线观看| 免费在线观看亚洲| 亚洲最新色图| 日韩一级裸体免费视频| 微拍福利一区二区| 精品日韩免费| 在线不卡国产精品| 日韩视频在线观看免费视频| re久久精品视频| 色阁综合伊人av| 日本黄色录像视频| 综合国产精品| 九九热这里只有精品免费看| 久久久精品视频免费观看| 欧美激情性爽国产精品17p| 欧美成人午夜影院| 日本一级黄色录像| 老司机午夜精品视频| 国产精品黄页免费高清在线观看| 亚洲欧美一二三区| 久久精品国产久精国产| 国产精品视频在线播放| 精品国自产在线观看| 91亚洲国产成人精品一区二三 | 日韩一级二级三级精品视频| 日本中文字幕有码| 欧美激情极品| 一区二区三区精品99久久| 韩国女同性做爰三级| 一个色综合网| 91精品国产高清久久久久久91| 99re这里只有精品在线| 丁香婷婷综合激情五月色| 免费成人深夜夜行视频| 国产黄a三级三级三级av在线看| 一区二区三区中文在线观看| 日韩精品―中文字幕| 久久国产精品美女| 亚洲色图15p| 国产在线免费视频| 激情成人综合网| 欧美日韩亚洲综合一区二区三区激情在线| 在线观看中文|