我的 github:github.com/iswbm/golangcodingtime
由於 go 使用的是詞法作用域,而詞法作用域依賴於語句塊。所以在講作用域時,需要先了解一下 go 中的語句塊是怎麼一回事?
通俗地說,語句塊是由花括弧({}
)所包含的一系列語句。
語句塊內部宣告的名字是無法被外部塊訪問的。這個塊決定了內部宣告的名字的作用域範圍,也就是作用域。
用花括弧包含的語句塊,屬於顯示語句塊。
在 go 中還有很多的隱式語句塊:
前面三點好理解,第四點舉幾個例子
for 迴圈完後,不能再使用變數 i
for i := 0; i < 5; i++
if 語句判斷完後,同樣不能再使用變數 i
if i := 0; i >= 0
switch 語句完了後,也是不是再使用變數 i
switch i := 2; i * 4
且每個 switch 語句的子句都是乙個隱式的語句塊
switch i := 2; i * 4
// "j" is undefined here
變數的宣告,除了宣告其型別,其宣告的位置也有講究,不同的位置決定了其擁有不同的作用範圍,說白了就是我這個變數,在**可用,在**不可用。
根據宣告位置的不同,作用域可以分為以下四個型別:
以上的四種作用域,從上往下,範圍從大到小,為了表述方便,我這裡自己將範圍大的作用域稱為高層作用域,而範圍小的稱為低層作用域。
對於作用域,有以下幾點總結:
在這裡要注意一下,不要將作用域和生命週期混為一談。宣告語句的作用域對應的是乙個源**的文字區域;它是乙個編譯時的屬性。
而乙個變數的生命週期是指程式執行時變數存在的有效時間段,在此時間區域內它可以被程式的其他部分引用;是乙個執行時的概念。
根據區域性作用域內變數的可見性,是否是靜態不變,可以將程式語言分為如下兩種:
具體什麼是動態作用域,這裡用 shell 的**演示一下,你就知道了
#!/bin/bash
func01()
func02() "
}# 執行函式
func01
func02
從**中,可以看到在 func01 函式中定義了個區域性變數 value,按理說,這個 value 變數只在該函式內可用,但由於在 shell 中的作用域是動態的,所以在 func01中也可以呼叫 func02 時,func02 可以訪問到 value 變數,此時的 func02 作用域可以當成是 區域性作用域中(func01)的區域性作用域。
但若脫離了 func01的執行環境,將其放在全域性環境下或者其他函式中, func02 是訪問不了 value 變數的。
所以此時的輸出結果是
func02 sees value as 1
func02 sees value as
但在 go 中並不存在這種動態作用域,比如這段**,在func01函式中,要想取得 name 這個變數,只能從func01的作用域或者更高層作用域裡查詢(檔案級作用域,包級作用域和內建作用域),而不能從呼叫它的另乙個區域性作用域中(因為他們在層級上屬於同一級)查詢。
import "fmt"
func func01()
func main()
因此你在執行這段**時,會報錯,提示在func01中的name還未定義。
參考文章:
01. 開發環境的搭建(goland & vs code)
02. 學習五種變數建立的方法
03. 詳解資料型別:****整形與浮點型
04. 詳解資料型別:byte、rune與string
05. 詳解資料型別:陣列與切片
06. 詳解資料型別:字典與布林型別
07. 詳解資料型別:指標
08. 物件導向程式設計:結構體與繼承
09. 一篇文章理解 go 裡的函式
10. go語言流程控制:if-else 條件語句
11. go語言流程控制:switch-case 選擇語句
12. go語言流程控制:for 迴圈語句
13. go語言流程控制:goto 無條件跳轉
14. go語言流程控制:defer 延遲呼叫
15. 物件導向程式設計:介面與多型
16. 關鍵字:make 和 new 的區別?
17. 一篇文章理解 go 裡的語句塊與作用域
18. 學習 go 協程:goroutine
19. 學習 go 協程:詳解通道/通道
20. 幾個通道死鎖經典錯誤案例詳解
21. 學習 go 協程:waitgroup
22. 學習 go 協程:互斥鎖和讀寫鎖
23. go 裡的異常處理:panic 和 recover
24. 超詳細解讀 go modules 前世今生及入門使用
25. go 語言中關於包匯入必學的 8 個知識點
26. 如何開源自己寫的模組給別人用?
27. 說說 go 語言中的型別斷言?
28. 這五點帶你理解go語言的select用法
go語言中的輸出語句
package main import fmt func main print println函式可以傳遞若干個引數,引數之間可以用逗號隔開 引數可以是字串 數字 數學表示式等 格式化列印 可以使用printf來控制列印的輸出結果,與print和println不同,printf的第乙個引數必須是字串...
Go語言中nil的理解
現在對於golang語言的介紹比較少,寫一點自己對於nil的理解。首先,我們取源 中看一下創始人是怎麼定義的nil 翻譯如下 nil是乙個預先宣告的識別符號,表示指標 通道 函式 介面 對映或切片型別。因此,我們可以知道nil只能表示指標 通道 函式 介面 對映或切片nil是go語言中預先的識別符號...
如何理解go語言中的閉包
對於閉包的理解,按照下面2點切入即可 1,閉包函式的返回值是函式 2,返回的函式繫結在閉包函式內乙個變數上。對於第2條如果不好理解的話,可以這麼理解。把外層的函式去掉,把函式內定義的變數想象成全域性變數,把返回的函式想象成普通函式。本質上,就是返回了乙個函式,這個函式內操作的變數是在另乙個函式中定義...