成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Int Make 居然不是關鍵字?

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

[[415774]]

本文轉載自微信公眾號「董澤潤的技術筆記」,作者董澤潤。轉載本文請聯系董澤潤的技術筆記公眾號。

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

我們知道每種語言都有關鍵字和保留字的,而 go 以關鍵字少著稱,只有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不是關鍵字,就連基本數據類型 int, int64, float 也都不是。但是 C 語言中關鍵字可是非常多的

make 內置函數

  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 變量類型是字符串。最后函數打印 hijacked. 顯然這段代碼很神經病,誰要這么寫會被打死,但確是可以編譯成功的

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

  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 的函數定義,大家可以看注釋或是看 builtin.go. make 接收三種類型參數:Map, Channel, Slice. 返回值是類型 T, 而不像 new 返回的是指針 *T

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

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,包括常見的整數類型,true, false, iota, nil 以及常用的函數 make, new, copy 等等,這些在其它語言可能都對應著關鍵詞 keywords 或是保留詞

從編譯原理的角度看,identifiers 和 keywords 關鍵詞沒有本質的區別,都是一個一個 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

 

責任編輯:武曉燕 來源: 董澤潤的技術筆記
相關推薦

2023-03-24 08:01:27

Go語言內存

2009-09-17 09:30:00

Linq LET關鍵字

2022-01-04 16:35:42

C++Protected關鍵字

2009-09-02 09:24:03

C# this關鍵字

2012-03-01 12:50:03

Java

2009-08-21 14:58:56

C# this關鍵字

2013-01-30 10:12:14

Pythonyield

2018-04-20 15:56:09

Pythonglobal關鍵字

2022-02-17 08:31:38

C語言staic關鍵字

2022-05-06 08:32:40

Pythonwith代碼

2022-06-29 08:05:25

Volatile關鍵字類型

2021-02-01 13:10:07

Staticc語言UNIX系統

2019-11-06 10:36:43

MavenoptionalJava

2009-08-13 13:04:29

C# lock關鍵字

2025-01-09 10:30:40

2019-12-20 15:19:41

Synchroinze線程安全

2009-12-17 13:57:15

Ruby關鍵字

2009-08-06 17:52:23

C#增加that關鍵字

2009-08-13 17:44:34

C# using關鍵字

2009-08-26 15:16:29

C# lock關鍵字
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 中文字幕精品一区二区三区精品 | 一区二区三区高清 | 九九99精品| 成人精品久久 | 精品一二区 | 久久久成人精品 | h视频在线免费看 | 美女黄色在线观看 | a毛片| 一区二区影视 | 美女福利网站 | 日本成年免费网站 | 神马久久久久久久久久 | 福利社午夜影院 | 成人亚洲综合 | 91嫩草精品| 99精品欧美一区二区三区综合在线 | 欧美日韩亚洲一区 | 精品国产不卡一区二区三区 | 午夜视频在线观看视频 | av免费网站在线观看 | 91国在线视频 | 淫片专区| 96久久久久久 | h视频免费在线观看 | 国产成人99久久亚洲综合精品 | 国产精品一区二区三区四区五区 | 久久久精品一区二区三区 | 一级黄色淫片 | 色综网 | 亚洲一区二区三区在线 | 日韩在线视频一区 | 成人天堂噜噜噜 | 国产成人免费一区二区60岁 | 日韩在线国产精品 | 日韩一区二区福利 | 精品国产一区二区三区久久久久久 | 91成人精品| 精品一区二区三区免费视频 | 欧美激情在线精品一区二区三区 | 国产线视频精品免费观看视频 |