官术网_书友最值得收藏!

7.7 變量作用域

現在你已經了解Scala內建的控制結構,本節將用這些內建的控制結構來解釋Scala的變量作用域。

Java程序員的快速通道

如果你是Java程序員,則會發現Scala的作用域規則幾乎與Java完全一樣。Java和Scala的一個區別是,Scala允許在嵌套的作用域內定義同名的變量。所以如果你是Java程序員,則最好至少快速地瀏覽一遍本節的內容。

Scala程序的變量在聲明時附帶了一個用于規定在哪里能使用這個名稱的作用域scope)。關于作用域,最常見的例子是代碼縮進一般都會引入一個新的作用域,因此在某一層縮進中定義的任何元素都會在代碼退回上一層縮進后離開作用域。我們可以看一下示例7.18中的函數。

示例7.18中的printMultiTable函數將打印出乘法表。[6]函數的第一個語句引入了名稱為i的變量并將其初始化成整數1,然后你就可以在函數的余下部分使用i這個名稱。

printMultiTable函數的下一條語句是while循環:

這里能用i,是因為它仍在作用域內。while循環中的第一條語句又引入了另一個名稱為j的變量,還是將其初始化成整數1。由于變量j是在while循環的縮進代碼塊中定義的,因此只能在while循環中使用它。如果你在while循環的縮進代碼塊之后(即那行提示你jprodk已超出作用域的注釋之后)還嘗試對j做任何操作,則你的程序將無法編譯。

示例7.18 打印乘法表時的變量作用域

本例中定義的所有變量(ijprodk)都是局部變量。這些變量只在定義它們的函數內“局部”有效。函數每次被調用,都會使用全新的局部變量。

一旦定義好某變量,就不能在相同的作用域內定義相同名稱的新變量。舉例來說,下面這段有兩個名稱為a的變量的腳本是無法通過編譯的:

不過,可以在一個內嵌的作用域內定義一個與外部作用域內相同名稱的變量。比如,下面的腳本可以正常編譯和運行:

這段腳本執行時,會先打印2再打印1,這是因為在if表達式中定義的a是不同的變量,這個變量只在縮進代碼塊結束之前處于作用域內。需要注意的一個Scala與Java的區別是,Java不允許在內嵌的作用域內使用一個與外部作用域內相同名稱的變量。在Scala程序中,內嵌作用域中的變量會“遮擋”(shadow)外部作用域內相同名稱的變量,因為外部作用域內的同名變量在內嵌作用域內將不可見。

你可能已經注意到如下在編譯器中類似遮擋的行為:

在編譯器中,可以隨心地使用變量名。其他的先不談,單這一點,就可以讓你在不小心定義錯了某個變量之后改變主意。之所以能這樣做,是因為從概念上講,編譯器會對你錄入的每一條語句創建一個新的嵌套作用域。

但是對于這樣的代碼,閱讀者會很困惑,因為變量在內嵌的作用域內是不同的含義。通常更好的做法是選一個新的有意義的變量名,而不是(用同樣的名稱)遮擋某個外部作用域的變量。

主站蜘蛛池模板: 盖州市| 漯河市| 肇东市| 石屏县| 桑日县| 廉江市| 长兴县| 安徽省| 浦东新区| 鄢陵县| 辉县市| 张家川| 遂平县| 安西县| 光泽县| 红河县| 潢川县| 乌恰县| 梁平县| 额济纳旗| 隆子县| 古丈县| 威远县| 方城县| 平谷区| 凭祥市| 察隅县| 穆棱市| 鄂托克前旗| 大丰市| 基隆市| 长沙县| 西吉县| 仁寿县| 桃源县| 扶风县| 喀喇沁旗| 杭州市| 江华| 共和县| 琼海市|