作用域
在電腦程式設計中,作用域(scope,或譯作有效範圍)是名字(name)與實體(entity)的綁定(binding)保持有效的那部分計算機程序。不同的編程語言可能有不同的作用域和名字解析。而同一語言內也可能存在多種作用域,隨實體的類型變化而不同。作用域類別影響變量的綁定方式,根據語言使用靜態作用域還是動態作用域變量的取值可能會有不同的結果。
命名空間是一種作用域,使用作用域的封裝性質去邏輯上群組起關相的眾識別子於單一識別子之下。因此,作用域可以影響這些內容的名字解析。
歷史
例子
下列例子顯示了C++語言中多種不同的作用域聲明:
namespace N
{ // 命名空间作用域,仅是群组织别名
class C
{ // 类作用域,定义/声明成员变量和函数
void f (bool b)
{ // 函数作用域,包含可执行语句
if (b)
{ // 条件执行语句的无名作用域
...
}
}
};
}
靜態作用域與動態作用域
靜態作用域又叫做詞法作用域,採用詞法作用域的變量叫詞法變量。詞法變量有一個在編譯時靜態確定的作用域。詞法變量的作用域可以是一個函數或一段代碼,該變量在這段代碼區域內可見(visibility);在這段區域以外該變量不可見(或無法訪問)。詞法作用域裡,取變量的值時,會檢查函數定義時的文本環境,捕捉函數定義時對該變量的綁定。
大多數現在程序設計語言都是採用靜態作用域規則,如C/C++、C#、Python、Java、JavaScript……
相反,採用動態作用域的變量叫做動態變量。只要程序正在執行定義了動態變量的代碼段,那麼在這段時間內,該變量一直存在;代碼段執行結束,該變量便消失。這意味着如果有個函數f
,裡面調用了函數g
,那麼在執行g
的時候,f
里的所有局部變量都會被g
訪問到。而在靜態作用域的情況下,g
不能訪問f
的變量。動態作用域裡,取變量的值時,會由內向外逐層檢查函數的調用鏈,並打印第一次遇到的那個綁定的值。顯然,最外層的綁定即是全局狀態下的那個值。
採用動態作用域的語言有Pascal、Emacs Lisp、Common Lisp(兼有靜態作用域)、Perl(兼有靜態作用域)。C/C++是靜態作用域語言,但在宏中用到的名字,也是動態作用域。