自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Int Make 居然不是關(guān)鍵字?

開發(fā) 前端
這是一個小白問題,有多少人知道 int 不是關(guān)鍵字?make 也不是關(guān)鍵字?我們知道每種語言都有關(guān)鍵字和保留字的,而 go 以關(guān)鍵字少著稱,只有25個。

[[415774]]

本文轉(zhuǎn)載自微信公眾號「董澤潤的技術(shù)筆記」,作者董澤潤。轉(zhuǎn)載本文請聯(lián)系董澤潤的技術(shù)筆記公眾號。

這是一個小白問題,有多少人知道 int 不是關(guān)鍵字?make 也不是關(guān)鍵字?

我們知道每種語言都有關(guān)鍵字和保留字的,而 go 以關(guān)鍵字少著稱,只有25個

  1. break        default      func         interface    select 
  2. case         defer        go           map          struct 
  3. chan         else         goto         package      switch 
  4. const        fallthrough  if           range        type 
  5. continue     for          import       return       var 

也就是說,我們常用的 make, cap, len不是關(guān)鍵字,就連基本數(shù)據(jù)類型 int, int64, float 也都不是。但是 C 語言中關(guān)鍵字可是非常多的

make 內(nèi)置函數(shù)

  1. package main 
  2.  
  3. import "fmt" 
  4.  
  5. func main(){ 
  6.     make := func() string { 
  7.         return "hijacked" 
  8.     } 
  9.  
  10.     int := make()    // Completely OK, variable 'int' will be a string 
  11.     fmt.Println(int) // Prints "hijacked" 

這段代碼 make 變量是一個閉包,返回一個字符串,而 int 變量類型是字符串。最后函數(shù)打印 hijacked. 顯然這段代碼很神經(jīng)病,誰要這么寫會被打死,但確是可以編譯成功的

同時如果想繼續(xù)用 make 創(chuàng)建 map, 或是用 int 聲明變量就會報錯。本質(zhì)上 make, cap, len 都是 go 源碼中的函數(shù)名,有點泛型的意思

  1. // The make built-in function allocates and initializes an object of type 
  2. // slice, map, or chan (only). Like new, the first argument is a type, not a 
  3. // value. Unlike new, make's return type is the same as the type of its 
  4. // argument, not a pointer to it. The specification of the result depends on 
  5. // the type: 
  6. // Slice: The size specifies the length. The capacity of the slice is 
  7. // equal to its length. A second integer argument may be provided to 
  8. // specify a different capacity; it must be no smaller than the 
  9. // length. For example, make([]int, 0, 10) allocates an underlying array 
  10. // of size 10 and returns a slice of length 0 and capacity 10 that is 
  11. // backed by this underlying array. 
  12. // Map: An empty map is allocated with enough space to hold the 
  13. // specified number of elements. The size may be omitted, in which case 
  14. // a small starting size is allocated. 
  15. // Channel: The channel's buffer is initialized with the specified 
  16. // buffer capacity. If zero, or the size is omitted, the channel is 
  17. // unbuffered. 
  18. func make(t Type, size ...IntegerType) Type 
  1. func len(v Type) int 
  1. func cap(v Type) int 

上面是 runtime 中對 make, len, cap 的函數(shù)定義,大家可以看注釋或是看 builtin.go. make 接收三種類型參數(shù):Map, Channel, Slice. 返回值是類型 T, 而不像 new 返回的是指針 *T

也就是說,變量名用 make, 只是在 main 函數(shù)這個詞法塊中普通的局部變量而己,同時遮蔽了 runtime 的 make 函數(shù)名

Predeclared identifiers

前面說的是 make, 那么對于 int 呢?其實道理也一樣,這些都是 go 預定義的標識符 Predeclared identifiers

  1. Types: 
  2.  bool byte complex64 complex128 error float32 float64 
  3.  int int8 int16 int32 int64 rune string 
  4.  uint uint8 uint16 uint32 uint64 uintptr 
  5.  
  6. Constants: 
  7.  true false iota 
  8.  
  9. Zero value: 
  10.  nil 
  11.  
  12. Functions: 
  13.  append cap close complex copy delete imag len 
  14.  make new panic print println real recover 

其實這些都 document 在 builtin.go,包括常見的整數(shù)類型,true, false, iota, nil 以及常用的函數(shù) make, new, copy 等等,這些在其它語言可能都對應著關(guān)鍵詞 keywords 或是保留詞

從編譯原理的角度看,identifiers 和 keywords 關(guān)鍵詞沒有本質(zhì)的區(qū)別,都是一個一個 token 而己

官方告訴我們,這些預定義的標識符在 universe block 塊中都是隱式定義的,所以我們才能直接用。那么什么是 universe block 呢?

  1. Block = "{" StatementList "}" . 
  2. StatementList = { Statement ";" } . 

除了上面這種顯示的語句塊,還有很多隱式的語句塊。大家要小心,因為很多時候 variable shadow 就是因為這個隱式的

  • The universe block encompasses all Go source text. 通用塊包括 go 源碼文本
  • Each package has a package block containing all Go source text for that package. 每個包都有一個塊,包含該包的所有 Go 源代碼
  • Each file has a file block containing all Go source text in that file. 每個文件都有一個文件塊,包含該文件中的所有 Go 源碼
  • Each "if", "for", and "switch" statement is considered to be in its own implicit block. 每個 if、for 和 switch 語句都被認為是在自己的隱式塊中
  • Each clause in a "switch" or "select" statement acts as an implicit block. switch 或 select 語句中的每個子句都是一個隱式塊

我們就犯過錯誤,命中了最后一條導致了變量 shadow. 那么問題來了,為什么 go 選擇預定義標識符的方式,而不是直接定義成 keywords 呢?Go prefers the universal block over keywords because declarations can be added to the universal block without breaking existing programs

 

責任編輯:武曉燕 來源: 董澤潤的技術(shù)筆記
相關(guān)推薦

2023-03-24 08:01:27

Go語言內(nèi)存

2009-08-21 14:58:56

C# this關(guān)鍵字

2013-01-30 10:12:14

Pythonyield

2018-04-20 15:56:09

Pythonglobal關(guān)鍵字

2009-09-02 09:24:03

C# this關(guān)鍵字

2009-09-17 09:30:00

Linq LET關(guān)鍵字

2012-03-01 12:50:03

Java

2022-01-04 16:35:42

C++Protected關(guān)鍵字

2009-08-06 17:52:23

C#增加that關(guān)鍵字

2019-12-20 15:19:41

Synchroinze線程安全

2024-03-15 15:12:27

關(guān)鍵字底層代碼

2009-08-13 17:44:34

C# using關(guān)鍵字

2009-08-21 14:47:59

C# base關(guān)鍵字

2009-12-17 13:57:15

Ruby關(guān)鍵字

2011-06-14 13:26:27

volatile

2022-01-10 18:11:42

C語言應用技巧

2009-08-26 15:16:29

C# lock關(guān)鍵字

2022-11-12 18:32:50

Golangomitemptyjson

2019-11-06 10:36:43

MavenoptionalJava

2009-08-13 13:04:29

C# lock關(guān)鍵字
點贊
收藏

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