在Swift程式中,每個「名稱」包括變數、常數、函式名稱等等,都有其個別的有效範圍,以範例1-5c為例,每個變數或常數的有效範圍如下圖:
說明如下:
① 下一個
「下一個」是迴圈內定義的「區域(local)常數」,每一次迴圈就會重新宣告,重新計算起始值,生命週期最短,只有一次迴圈。
② i
i 是for的「迴圈參數」,生命週期從進入迴圈到整個脫離迴圈為止。i 不能在迴圈內被修改,事實上它是一個常數,每次迴圈會重新定義,自動給予新的值。
③ m
m 是函式內定義的「區域常數」,生命週期從宣告到函式結束為止,每次函式呼叫時就會重新定義
④ n
n 是函式本身的「參數」,生命週期從進入函式到函式結束為止。大部分的參數在函式內不能被修改(稱為"Call by value"),如這個 n,但有些情況下,允許修改(稱為"Call by reference"),後面遇到再解釋。
⑤ 陣列, 最大索引
「陣列」與「最大索引」是程式的「全域(global)變數」,在整個程式範圍內都有效,生命週期從宣告起到整個程式結束,生命週期最長。
注意我們在①最內圈變更了「數列」這個全域變數,因為它的有效範圍是涵蓋整個程式,所以即便離開迴圈、離開函式,被改變的結果仍是有效的,不會被還原。
在比較複雜的程式裡面,特別是多人共同做的專案中,這樣的用法並不好,因為你不知道全域變數會在哪裡被改過,很難追蹤和debug,也就是說,「全域變數」盡量少用。但「全域常數」則沒有這個顧慮。
除了變數或常數之外,任何命名的名稱都有類似的有效範圍,如果在內圈的命名與外圈重複,會取用較內圈的變數,如下例。
// 1-5f 變數有效範圍
// Created by Heman, 2021/07/19
let i = 10
for i in 1...9 {
print(i)
}
print(i)
在for迴圈內 print(i) 取的是迴圈參數 i,所以印出1到9,而最後一行 print(i)取的是全域常數 i,印出10。
變數、常數等名稱的範圍(Scope)是程式設計很重要的概念,範圍不同,程式的邏輯會跟著不同。在不同範圍內,取相同變數名稱,容易導致邏輯錯誤,但有時又很難避免,只能靠正確的觀念,細心地去debug。