2016-04-29 18 views
6

據我所知,在語言如Haskell中,並且也可作爲演算的一部分,每個拉姆達表達式都有自己的範圍,因此,如果我有嵌套lambda表達式如:\x -> (\x -> x)則第一\x參數是到所述第二不同\x爲什麼java lambda表達式不會引入新的範圍級別?

在Java中,如果你這樣做,你會得到一個編譯錯誤,就像你再次使用x作爲參數名稱或者lambda中的一個局部變量名,如果它已經在封閉範圍內使用的話。作爲方法參數。

有誰知道爲什麼Java實現的lambda表達式這種方式 - 爲什麼不把他們介紹的範圍內一個新的水平和表現得像一個匿名類會嗎?我假設這是因爲一些限制或優化,或者可能是因爲lambda必須被黑入現有語言?

+0

你如何參考外X在這樣的語言中嵌套拉姆達內? –

+1

@SotiriosDelimanolis你不一定要能夠做到這一點,這是一個設計決定。你可以e。 G。也不能從一個匿名類訪問局部變量x,在那裏定義另一個非常有效的x。 – Vampire

+2

[Variable已經在方法lambda中定義]的可能重複(https://stackoverflow.com/questions/22773003/variable-is-already-defined-in-method-lambda) – ZhekaKozlov

回答

10

這與Java中其他代碼塊的行爲相同。

這給出了一個編譯錯誤

int a; 
{ 
    int a; 
} 

雖然這並不

{ 
    int a; 
} 
{ 
    int a; 
} 

你可以閱讀有關此主題的section 6.4 of the JLS,具有一定的推理在一起。

3

一個lambda塊一個新的塊,又名作用域,但它並沒有像匿名類實現那樣建立新的上下文/級別。

從Java語言規範15.27.2 Lambda Body

與出現在匿名類聲明的代碼,名稱的含義,並出現在拉姆達身體,用引用聲明的無障礙沿thissuper關鍵字,是與周圍環境相同(除了lambda參數引入新名稱)。

而且從JLS 6.4 Shadowing and Obscuring

這些規則允許在嵌套類聲明(局部類(§14.3)和匿名類可變或局部類重聲明§15.9 ))發生在變量或本地類的範圍內。因此,形式參數,局部變量或局部類的聲明可以嵌套在嵌套在方法,構造函數或lambda表達式中的類聲明中;並且可以在嵌套在catch子句的Block內的類聲明中隱藏異常參數的聲明。

有兩種設計方案可用於處理由lambda參數和lambda表達式中聲明的其他變量創建的名稱衝突。一種是模仿類聲明:就像本地類一樣,lambda表達式爲名稱引入一個新的「級別」,並且可以重新聲明表達式外的所有變量名稱。另一個是「本地」策略:與catch子句,for循環和塊一樣,lambda表達式與封閉上下文在相同的「級別」下運行,並且表達式之外的局部變量不能被映射。 以上規則使用本地策略;沒有特殊的配置允許在lambda表達式中聲明的變量映射在封閉方法中聲明的變量。

例子:

class Test { 
    private int f; 
    public void test() { 
     int a; 
     a = this.f;  // VALID 
     { 
      int a;  // ERROR: Duplicate local variable a 
      a = this.f; // VALID 
     } 
     Runnable r1 = new Runnable() { 
      @Override 
      public void run() { 
       int a;   // VALID (new context) 
       a = this.f;  // ERROR: f cannot be resolved or is not a field 
           // (this refers to the instance of Runnable) 
       a = Test.this.f; // VALID 
      } 
     }; 
     Runnable r2 =() -> { 
      int a;  // ERROR: Lambda expression's local variable a cannot redeclare another local variable defined in an enclosing scope. 
      a = this.f; // VALID 
     }; 
    } 
} 
+0

那麼他們爲什麼做出這個決定,是有沒有限制,這意味着他們不能,或者他們沒有這樣做的好處,即沒有每個lambda的新的範圍水平? – Tranquility

相關問題