程式語言的執行順序一般都是由上往下,逐行執行。不過有一些語句,可以改變執行的流程,我們稱之為「控制流程語句 (Control flow statement)」
將條件 (bool) 置入If 中,當條件成立,則執行 if 語句,否則執行 else。
var state = true;
if(state){
print('state is true');
}else{
print('state is false');
}
還可以在if-else 中間插入其他的判斷條件,用 else if 關鍵字做判斷。
var point = 10;
if(ponint < 10){
print('point is less than 10');
}else if(point < 50){
print('point is less than 50');
}else{
print('point is $point');
}
如果有多個條件,請使用 switch。
用 for 可以依序走訪列表的每一個元素。
var list = ['Tiger', 'Lion', 'Eagle'];
for(var i=0; i<list.length; i++){
print(list[i]);
}
在 for 迴圈中,開始與結束的數值都可以自己調整。
若是 Iterable 類的子類別,如 List,Set...
如果需要走訪每一個元素,可以使用 for-in 迴圈:
所以可以將上例改為:
var list = ['Tiger', 'Lion', 'Eagle'];
for(var item in list){
print(item);
}
for-in 迴圈不需要指定開始與結束的位置,它只是將集合類裡面的每一個元素依序列出。
所以 for 迴圈每一次都會產生新的索引值,而 for-in 迴圈,每一次都會產生一個集合類裡面的元素。
在 Dart
中,集合函數的索引值是由 0 開始計算,所以最大值會是 list.length -1。
但是在 for 迴圈中,開始與結束的位置是自己定義的,若是超出集合類的大小,就會發生錯誤。
例如:某工程師將 List 的索引值記成由 1 開始,那麼,他有可能會寫出底下的程式。
當 i 的值到 3 時,因為list[3] 是不合法的,所以會發生錯誤。
var list = ['Tiger', 'Lion', 'Eagle'];
for(var i=1, i<=list.length; i++){
print(list[i]);
}
當條件成立,則會持續在 while
迴圈裡執行。
var i = 0;
while(i<=10){
print(i);
i++;
}
//0
//1
//2
//3
//4
//5
//6
//7
//8
//9
//10
會先執行一次,接者才會執行 while 迴圈。
var state = false;
do{
print('state is $state');
}while(state);
//state is false
在 while 迴圈中,一般都是等到條件不成立之後,才可以跳出迴圈。
但是,利用關鍵字 break
,可以直接跳出迴圈,而不需等到條件不成立。
var i = 0;
while(i<=10){
print(i);
i++;
if(i == 4) break;
}
//0
//1
//2
//3
同樣的,我們也可以把 break 用在 for 迴圈上。
var list = ['Tiger', 'Lion', 'Eagle'];
for(var i=0, i<list.length; i++){
print(list[i]);
if(list[i]=='Lion') break;
}
//Tiger
//Lion
關鍵字 break
是將跳出迴圈,如果我們想要繼續完成迴圈,但是某些迴圈的條件我們不考慮呢?
利用關鍵字 contiune
可以跳到迴圈的下一次進行。
for(var i=0; i<10; i++){
if(i%2 == 1) continue;
print(i);
}
//0
//2
//4
//6
//8
上面範例,我們想列印出 0~9 中,偶數的部分。我們將每一次迴圈得到的 i 做餘數計算,餘數為 1 ,表示該數字為奇數,利用後方的 continue 關鍵字繼續下一次迴圈,所以下一行的 print(i) 就不會被執行到。
當然 continue 也可以用在 while 迴圈內。
在 for 迴圈的介紹裡,我們提到應避免使用 else if ,要使用 switch 。
var sport = 'baseball';
switch (sport){
case 'baseball':
playBaseball();
break;
case 'basketball':
playBasketball();
break;
default:
print('$sport is not ready');
break;
}
同樣的範例,我們用 if - else if - else 來改寫
var sport = 'baseball';
if(sport == 'baseball'){
playBaseball();
} else if(sport == 'basketball'){
playBasketball();
}else{
print('$sport is not ready');
}
我們要判斷 sport ,在每一個 if/else if 裡,我們都會看到 sport ==
的程式碼,這會造成多餘的 code。
enum
是一種型別,用於自定義 type,若用在 switch 上,IDE 會自動告訴我們有哪一個 enum 尚未考慮到。
enum
?用關鍵字 enum
加上 enum 名稱,用大括弧定義所有的情況。
範例:有一個 enum 型別,名稱為 NetworkState。我們定義三種情況:1. online,2. offline, 3. airplane_mode。
enum NetworkState{online, offline, airplane_mode}
void checkNetworkState(NetworkState networkState){
switch(networkState){
case online:
print('Online');
break;
case offline:
print('Offline');
break;
case airplane_mode;
print('Airplane Mode');
break;
}
}
承上所述,用 switch case 判斷 enum 值,若 switch case 裡的數量與 enum 數量不符合時,IDE 會跳出警告,讓我們可以注意補上漏掉的 case。
例如:上面的範例,我們少寫了 airplane_mode
void checkNetworkState(NetworkState networkState){
switch(networkState){
case NetworkState.online:
break;
case NetworkState.offline:
break;
}
}
→ 結果 IDE 就跳出警告通知我。
在 switch 中,除了可以用 case 定義每一個情況所要執行的運算式,還可以把剩下沒定義的用關鍵字 default 定義。
例如:上面少一個 case 的範例,我們可以用 default 補上。
void checkNetworkState(NetworkState networkState){
switch(networkState){
case NetworkState.online:
break;
case NetworkState.offline:
break;
default:
break;
}
}
當使用 switch case 時,必須要注意是否每一個 case 都有相對應的 break;。
當定義 case 卻沒有 break; ,此時在此 case 底下的 case 就會被呼叫到。
如下:有名工程師,將 case online:
的 break;
忘了寫。
void checkNetworkState(NetworkState networkState){
switch(networkState){
case online:
print('Online');
case offline:
print('Offline');
break;
case airplane_mode;
print('Airplane Mode');
break;
}
}
void main(){
checkNetworkState(NetworkState.online);
}
//Online
//Offline
checkNetworkState
帶入 NetworkState.online 時,除了自己本身的運算式,連帶下一個運算式也被呼叫了。除了關鍵字 break
可以跳出 switch 之外,關鍵字 continue
、throw
或是 return
都可以跳出 switch。
在開發中,我們有可能會需要確定某些地方的值是否如我們預期,我們可以用關鍵字 assert
。
例如:我們希望該函數 showName 沒有空值傳進來,我們可以在函數裡面加上 assert
,當在 debug 模式發生傳入 showName 的值為空時,此時就會發生錯誤。
void showName(String name){
assert(name !=null );
print('$name')
}
幾乎所有程式語言都有控制流程語句,它也是基本程式語言的基本功夫之一。但是,越容易的東西,越容易誤用,越用越糟。
如引言所述,程式語言是依序執行,如果控制流程語句用得太多,執行順序也會因此改變很多,那麼維護的時候就會變得很不容易。
if-else, switch 算是條件判斷類,一定要把每一個條件都判斷清楚,才不會有遺漏的情況,造成誤動作。所以判斷兩個情況,建議使用 if-else,多個情況可以使用 switch 搭配 enum。
使用 for 迴圈時,一定要注意迴圈的起始值,如果是迭代類 (iterable), 建議使用 for-in 迴圈,或是forEach 函數。
最後是 while,使用 while 一定要注意條件有沒有辦法變成不成立,否則無窮迴圈就會等著你。