Sway 參考手冊/迴圈
有時,程式設計師希望多次執行一段程式碼。這種任務通常使用迴圈來完成。Sway 中最基本的迴圈結構是 while 迴圈,其格式為...
whileloop: 'while' '(' expr ')' block
其中 expr 是任何解析為符號 :true 或 :false 的 Sway 表示式。
while 迴圈在執行迴圈主體之前測試其條件。如果初始測試失敗,則主體根本不會執行。例如;
var i = 10;
while (i < 10)
{
print(i);
i = i + 1;
}
不會列印任何內容,因為測試立即失敗。在這個例子中,然而
var i = 0;
while (i < 10)
{
print(i);
i = i + 1;
}
迴圈打印出數字 0 到 9
0123456789
while 迴圈重複執行其主體(迴圈的塊部分)(只要條件保持為 true)。
要編寫一個無限迴圈,請使用 :true 作為測試表達式
while (:true)
{
var i = getInput();
process(i);
}
與 if 一樣,所有 Sway 迴圈都是函式呼叫,通常帶有近似塊引數。如果需要,可以將小的近似塊作為常規引數移到括號內。此外,if 的分號規則也適用於迴圈:迴圈本身具有近似塊引數,後面不加分號。如果你要使用迴圈的返回值(對於 while,如果測試表達式最初為 true,則為 :true,如果測試表達式最初為 false,則為 :false),你需要在整個表示式後加上分號。
因為迴圈在 Sway 中很容易編寫,所以只有 while 迴圈是內建的。其他迴圈可以在 "basics" 庫中找到。要使用 "basics" 庫,請新增函式呼叫
include("basics");
到原始碼檔案的最頂端。
do-until 迴圈類似於 while 迴圈,但迴圈的主體在進行測試之前執行一次。例如
var i = 10;
do-until (i == 10) //note the test
{
print(i);
i = i + 1;
}
打印出 i 的值一次
10
請注意,do-until 在測試成功之前執行,這與 while 相反,while 在測試失敗之前執行。
do-until 迴圈並不經常使用,儘管有時它對於處理互動式輸入很有用。你總是可以將 do-until 編寫為 while 迴圈。考慮這個迴圈
do-until (r == 0)
{
r = n / d;
n = d;
d = r;
}
它可以被重寫為一個 while 迴圈,如下...
finished = :false;
while (!finished)
{
r = n / d;
n = d;
d = r;
finished = (r == 0);
}
請注意,變數 finished 被初始化為 :false,以確保迴圈主體至少進入一次。在迴圈底部,finished 被設定為 do-until 測試結果。
通常,do-until 更易於閱讀和理解。
在許多程式中發現的另一個迴圈是 for 迴圈。for 迴圈由四個主要部分組成
- 初始化步驟
- 測試
- 主體
- 更新
請注意,這些元件與 while 迴圈完全對應
i = 0; // initialize
while (i < MAX) // test
{ // body
inspect(i);
i = i + 1; // update (in body)
}
其中更新通常是迴圈主體中的最後一條語句。相應的 for 迴圈為
for (i = 0, i < MAX, i = i + 1) // init, test, update
{ // body
inspect(i);
}
看看更新是如何從主體中移出的。
for 迴圈通常用於遍歷陣列中的每個元素
for (i = 0, i < length(items), i = i + 1)
{
a[i] = b[i] * c[i];
}
for 迴圈是一個計數迴圈。對於大多數(但並非全部)計數迴圈,迴圈變數(在本例中為 i)被初始化為零,迴圈測試(在本例中為i < length(items)) 被配置為只要迴圈變數嚴格小於計數的最大值就成功。如果迴圈主體要執行 n 次,則迴圈看起來像
for (i = 0, i < n, i = i + 1)
{
...
}
這種約定源於 Sway 中的陣列(在後面的章節中詳細介紹)使用 "基於零的索引"。也就是說,陣列的第一個元素位於索引零處,第二個元素位於索引一處,依此類推。
除非有充分的理由,否則你應該始終使用這種約定[1]。
for-each 迴圈對於遍歷陣列和列表也很有用。它沒有明確計數,但是
for-each (s,items)
{
inspect(s);
}
在這個迴圈中,items 中的每個元素依次繫結到變數 s。迴圈主體執行的次數與陣列或列表中的元素數量相同。請注意,與等效的 for 迴圈相比,for-each 迴圈要短得多
for (i = 0; i < length(item); i = i + 1)
{
var s = items[i];
inspect(s);
}
它明確地計數。
除了迴圈條件或測試失敗(或在 do-until 的情況下成功)之外,還有許多方法可以退出迴圈。即使在迴圈中間,也可以從函式中返回。這種技術經常用於搜尋陣列
function find(x,items)
{
var s;
for-each(s,items)
{
if (x == s)
{
return :true;
}
}
:false;
}
請注意,如果未找到該專案,則迴圈最終會終止,並透過返回 :false 來表示失敗。
你也可以透過呼叫 break 來退出迴圈,而無需完全退出函式
i = 0;
while (i < 10)
{
if (i > 5) { break(); }
inspect(i);
}
println(:done);
執行此程式碼將產生
i is 0 i is 1 i is 2 i is 3 i is 4 i is 5 done
你需要包含 basics 才能使用 break。你也可以簡單地丟擲一個型別為 :break 的異常
i = 0;
while (i < 10)
{
if (i > 5) { throw(:break,0); }
inspect(i);
}
println(:done);
最後,你可以透過使用 exit 函式來退出程式來退出迴圈
while (1)
{
var input = getInput();
if (reallyBad(input))
{
exit(-1); //non-zero exit code
}
}
按照慣例,退出程式碼為零的 Sway 程式表示處理正常進行。非零退出程式碼表示發生某種致命錯誤。
- ↑ 相信我吧。