作用域(scope), 定義空間(declaration space) 和 生存期(lifetime)

weixin_30924079發表於2020-04-04

譯自Eric Lippert's Blog, 原文: http://blogs.msdn.com/ericlippert/archive/2009/08/03/what-s-the-difference-part-two-scope-vs-declaration-space-vs-lifetime.aspx

   在程式語言設計中,作用域(scope)通常是最容易混淆的概念。

    人們似乎不經意間就使用這個概念,我經常看到它被當做生存期(lifetime)或定義空間(declaration space)使用,例如"當這個變數超出作用域時,對應的記憶體空間將被釋放"。當然在非正式場合,只要聽眾能清楚地理解你所指的意思,使用"作用域"來表示是完全可以接受的。但是在更正式的場合,比如書中或語言標準中,就需要更精確地使用這些概念。

    C#中作用域和定義空間的區別是微妙的。

    一個命名實體(entity)的作用域是原始碼中可以合法使用它的非限定名(unqualified name)來引用它的範圍。

    這裡有些微妙的東西, 這個定義並沒有別的隱含的意思 -- 它並非表示如果你可以合法使用一個實體的非限定名,則通過這個非限定名就可以引用這個實體。因為作用域是允許重疊(overlap)的。例如,如果有以下程式碼:

class C

{

  
int x;

  
void M()

  {

    
int x;

  }

}

    欄位x(field)的作用域是原始碼中類C(class)的整個定義部分,包括方法M(method)的整個定義;區域性變數x(local variable)的作用域是方法M的主體部分。所以這兩個實體的作用域有重疊的部分。當你在不同的位置使用非限定名"x",將得到不同的實體(欄位x或者區域性變數x)。

    相反, 定義空間是一段其中不允許存在具有相同名稱實體的原始碼範圍。例如,在類C的定義部分,除了方法M的主體部分,不允許別的實體也命名為x。一旦定義了個欄位x, 就不能再定義別的稱為x的欄位,屬性(property), 內嵌型別(nested type)或事件(event)。

    正因為有過載機制(overload), 使得方法有一點特殊。可以特別定義有方法的定義空間為"一個類中所有具有相同名稱的過載方法構成一個實體", 也可以重新定義定義空間為"定義空間中不允許存在具有相同名稱的實體, 除了具有不同簽名(signature)的方法"。

    簡短地說,作用域解決了“在哪裡可以使用這個名稱”的問題;名稱空間解決了“這個名稱在哪裡是唯一的”的問題。

    生存期和作用域經常在區域性變數上容易混淆,因為在區域性變數上這兩者關係太複雜了。扼要地講,就是隻要當前的執行點(point of execution)在區域性變數的作用域內,至少能保證它的內容可用。但也可能區域性變數的內容在超出它的作用域外也是可用的,比如捕獲變數(capture variable, variable capturing , 在匿名函式中使用外部變數 )將擴充套件這個變數的生存期。

轉載於:https://www.cnblogs.com/tommyli/archive/2009/10/16/1584517.html

相關文章