이전까지 다트에서 사용하는 타입들의 사용법에 대해 익혀봤다.
이번에는 다트를 이용해 흐름을 지정할 수 있는 방법에 대해 알아보자.
다트는 if / else if / else
, switch-case
를 이용해 흐름을 지정할 수 있으며, for
, while
, do while
을 이용해 반복을 사용할 수 있다. 각각을 살펴보자.
if
, else
, else if
가장 기본적인 조건을 만드는 방법으로, if (statement) {code}
로 사용한다.
statement
에는 반드시 bool
타입 데이터를 넣어야 하며, 다른 언어에서 제공하는 암시적 타입을 사용한 if문의 사용은 허용되지 않는다.var isDart = true;
print('이 부분은 항상 출력됩니다.');
if (isDart == true) { // isDart의 값이 true이기 때문에 해당 식의 결과는 true이다.
print('이 부분은 isDart 변수가 참일 경우에만 출력됩니다.');
}
if (isDart) { // isDart 자체가 bool 타입의 true이기 때문이 이것도 참이다.
print('isDart가 참이면 이것도 출력됩니다.');
}
만약 조건이 참이면 A를 하고 그렇지 않으면 B를 수행해줘
라는 코드를 짜기 위해서 else
가 존재한다.else
는 단독으로 사용될 수 없으며, 반드시 if
와 같이 쌍으로 사용되어야 한다.else
는 if
의 조건이 참이 아닐 경우에 수행되기 때문에 별도의 조건을 작성하지 않는다는 것을 명심하자.var myAge = 28;
print('이 부분은 항상 출력됩니다.');
if (myAge > 30) { // myAge가 30보다 크면 true, 아니면 false가 반환된다.
print('이 부분은 myAge 변수가 30보다 클 경우에만 출력됩니다.');
} else { // 위 if문이 거짓이면 자동으로 수행되기 때문에 별도의 조건을 작성하지 않는다.
print('이 부분은 myAge 변수가 30보다 작거나 같을 경우에만 출력됩니다.');
}
만약 조건1이 참이면 A를 하고 그렇지 않고 조건2가 참이면 B를 하고 그렇지 않으면 C를 수행해줘
라는 코드를 짜기 위해서 else if
가 존재한다.else if
는 else
처럼 단독으로 사용될 수 없으며, 반드시 if
와 같이 사용되어야 한다.else
는 각 조건문의 마지막에 한번만 사용될 수 있지만, else if
는 if
아래, else
위에 필요한 조건의 수만큼 사용할 수 있으며, 각 조건은 위에서 아래로 순서대로 체크하다 true
가 나올 때 멈추게 되며, 모든 조건이 참이 아니면 else
가 실행된다.var myScore = 75;
if (myScore > 90) { // myScore 변수가 90보다 크면 수행
print('점수가 90점보다 높습니다!');
} else if (myScore > 80) { // 위 조건이 거짓이고 myScore 변수가 80보다 크면 수행
print('점수가 80점보다 높습니다');
} else if (myScore > 70) { // 위 조건이 거짓이고 myScore 변수가 70보다 크면 수행
print('점수가 70점보다 높습니다..');
} else { // 그 외 경우라면 수행
print('점수가 너무 낮습니다...');
}
switch - case
if
문은 각각의 조건이 독립된 조건으로 이루어져 있어서 서로 관련없는 데이터를 조건문으로 사용할 수 있다. switch
문은 하나의 데이터를 기준으로 다양한 case
로 비교하는 조건문이라 할 수 있다.
switch (variable)
에 들어가는 variable
은 ==
를 사용하여 비교되기 때문에 ==
를 override하면 일반적으로 사용할 수 없다.(hashCode를 같이 override하면 되는것 같기도...)case statements:
형식으로 사용하고, 그 아래에 해당 내용을 작성한다.break
문을 작성하여 해당 구문이 끝났음을 알려주어야 한다. 만약 break
를 사용하지 않으면 해당 조건이 if
문의 else
처럼 모든 조건이 일치하지 않으면 실행되는 default
문을 사용할 수 있으며, default
는 조건의 맨 아래에 사용되기 때문에 별도의 break
를 사용하지 않아도 된다.var subject = '수학';
switch (subject) { // String 타입의 '수학' 문자열이 비교 대상이 된다.
case '국어': // '수학' == '국어' 비교를 통해 참/거짓을 확인하고 참일 경우 아래를 수행한다.
print('국어입니다!');
break; // case가 종료될 때 반드시 break를 작성하여 해당 구문을 끝내도록 한다.
case '수학': // '수학' == '수학' 비교를 통해 참/거짓을 확인하고 참일 경우 아래를 수행한다.
print('수학입니다!');
break;
case '영어': // '수학' == '영어' 비교를 통해 참/거짓을 확인하고 참일 경우 아래를 수행한다.
print('영어입니다!');
break;
default: // 위 모든 조건이 거짓일 경우 수행되는 구문이다.
print('잘 모르겠습니다...'); // default 아래에는 별도의 구문이 없기 때문에 아래에 break를 작성하지 않아도 된다.
}
label
과 continue
switch문에서는 label
과 continue
를 이용하여 좀 더 복잡한 조건을 사용할 수 있다.
만약 값이 30일 땐 그냥 30을 출력하고, 10인 경우엔 10을 출력한 뒤 30도 출력하고 싶다고 하면 아래와 같이 사용할 수 있다.
label
을 labelName:
형태로 사용하고, 다른 case에서 continue labelName
형태로 사용할 수 있다.continue
를 사용하고 아래에 break
를 작성하지 않아도 되는데, 이는 continue
를 수행하면 해당 구문이 종료되고 라벨명쪽으로 흐름이 이동되기 때문이다.var data = 10;
switch(data) {
case 10: // data == 10 이 참일 때만 수행한다.
print('10입니다.');
continue test; // 본 case가 끝나면 test 라벨 구문으로 이동해서 다음을 수행하라는 명령이다.
case 3: {
print('3입니다.');
break;
}
test: // test 라벨이 작성된 곳으로, 라벨은 case 위에 존재해야 한다.
case 30:
print('30입니다.');
break;
default:
print('모르겠어요...');
}
for
반복 횟수를 지정하고 반복을 수행하는 기능으로, for (초기식;조건식;증감식)
의 형태로 사용된다. 초기식을 기준으로, 조건식이 참이면 반복문 내에 있는 기능을 수행하고 증감식을 수행한다. 이후 조건식을 확인하며 거짓이 될 때까지 반복한다.
var localVar = 0;
형식으로 반복문 내에서 사용할 변수를 초기화 한다.localVar < 10;
형식으로 반복문이 수행할 조건을 작성해 준다. 예시는 localVar이 10보다 작을 때만 수행한다는 뜻이다.localVar++
형식으로 반복문 내에서 변화할 내용을 작성해 준다. 예시는 localVar를 1씩 증가시킨다는 뜻이다.for (int i = 0; i< 10; i++){ // 0부터 9까지 1씩 증가하며 반복한다.
print('${i}');
}
for-in
다트는 Iterable 객체를 대상으로 for-in
을 지원한다. Iterable이라는 말이 어려울 수 있는데, 지금은 List
, Set
같은 데이터라고 생각하면 될 것 같다. 쉽게 말해 내부적으로 반복할 수 있는 기능이 들어있는 객체들을 말한다. 내부적으로 기능이 있기 때문에 기존의 for
문 처럼 사용하지 않아도 더 간편하게 사용할 수 있다.
for (var localVar in iterable)
형식으로 사용하며, 본 기능은 Iterable에 한해서 사용할 수 있다.var myList = [1,2,3,4,5];
for (var element in myList) { // 반복문 내에서 사용할 로컬 변수 element를 지정하여 사용한다.
print('element: ${element}');
element += 10;
}
print('myList: ${myList}');
// 로컬 변수에 final 키워드를 이용하면 반복문 내에서 변수의 값이 변경되는 것을 방지할 수 있다.
// 근데 var로 해도 원본 데이터엔 반영이 안되는 것을 보니 for in은 값의 복사로 이루어지는 것 같다.
for (final element in myList) {
print('element: ${element}');
element += 10; // [ERROR] final로 선언한 데이터를 변경하려 해서 에러 발생
}
print('myList: ${myList}');
while
, do while
for
문이 수행 횟수가 정해진 반복문이라면, while
과 do while
은 횟수가 아닌 조건만을 따지는 횟수가 정해지지 않은 반복문이다. `while은
while(조건)
형식으로 사용하며, 반복문 내 내용을 수행 후 조건이 거짓인지 확인하고 거짓이 될 때까지 반복한다. 따라서 조건 설정을 신중하게 하지 않으면 무한루프에 빠질 수 있으니 주의해야 한다.int cnt = 0; // while문의 조건식에서 사용할 변수를 선언
while (cnt<10) { // cnt가 10보다 작을 때만 반복문 내용을 수행한다.
print('cnt: ${cnt}');
cnt++;
}
print('-'*20); // -를 20번 반복하여 출력
// flag용 변수를 지정하고 반복문 내에서 플래그를 변경하여 반복문을 컨트롤할 수 있다.
int cnt2 = 0;
bool flag = true;
while (flag) {
cnt2++;
if (cnt2 > 10) { // cnt 값이 10보다 크면 flag 변수를 false로 바꿔 반복문이 종료될 수 있도록 한다.
flag = false;
}
print('cnt2: ${cnt2}');
}
print('-'*20); // -를 20번 반복하여 출력
// do while은 조건을 검사하기 전에 최소 한번 수행 하는 것만 다르다.
// 조건을 만족하지 않으면 실행을 하지 않는 while과 다르게, do while은 조건을 만족하지 않아도 최소 한 번은 수행한다.
int cnt3 = 0;
do {
print(cnt3);
cnt3++;
} while(cnt3<10);
결과
cnt: 0
cnt: 1
cnt: 2
cnt: 3
cnt: 4
cnt: 5
cnt: 6
cnt: 7
cnt: 8
cnt: 9
--------------------
cnt2: 1
cnt2: 2
cnt2: 3
cnt2: 4
cnt2: 5
cnt2: 6
cnt2: 7
cnt2: 8
cnt2: 9
cnt2: 10
cnt2: 11
--------------------
0
1
2
3
4
5
6
7
8
9
continue
, break
반복, 분기가 존재하는 경우, continue
또는 break
를 사용할 수 있다.
보통 for
, while
, switch
등에서 사용한다.
continue
: 여기까지 진행하고 처음으로 돌아간다. 일부의 경우 뒤에 라벨을 붙여 해당 부분으로 이동할 수도 있다.break
: 여기까지만 진행하고 해당 구문을 종료한다. 일부의 경우 뒤에 라벨을 붙여 해당 부분을 종료할 수도 있다.int i = 0;
while (true) {
i++;
if (i < 5) { // i가 5보다 작을 때만 수행된다.
print(i);
continue; // continue 문을 만나면 이후 작업을 수행하지 않고 반복문의 처음(조건)으로 돌아간다.
}
if (i == 10) {
print('i의 값이 10이 되어 반복문을 종료합니다.');
break; // break 문을 만나면 이후 작업을 진행하지 않고 반복문을 빠져나갑니다.
}
print('이 부분은 i가 5 이상일 때만 출력됩니다. -> i: ${i}');
}
결과
1
2
3
4
이 부분은 i가 5 이상일 때만 출력됩니다. -> i: 5
이 부분은 i가 5 이상일 때만 출력됩니다. -> i: 6
이 부분은 i가 5 이상일 때만 출력됩니다. -> i: 7
이 부분은 i가 5 이상일 때만 출력됩니다. -> i: 8
이 부분은 i가 5 이상일 때만 출력됩니다. -> i: 9
i의 값이 10이 되어 반복문을 종료합니다.
continue
및 break
반복문 위에 라벨을 작성하여 continue 및 break를 사용할 수 있다.
outerLoop: // 외부 루프 라벨
for (var i = 0; i<5; i++) {
innerLoop:
for (var j = 0; j<5; j++) {
if (i == 2) {
print('outerLoop를 continue합니다.');
continue outerLoop; // 외부 반복문을 패스하는 기능
}
if (j == 3) {
print('innerLoop를 continue합니다.');
continue innerLoop; // 내부 반복문을 패스하는 기능
}
if (i == 4) {
print('outerLoop를 break합니다.');
break outerLoop; // 외부에 있는 반복문을 한번에 빠져나갈 수 있는 좋은 기능
}
print('i: ${i}, j: ${j}');
}
}
결과
i: 0, j: 0
i: 0, j: 1
i: 0, j: 2
innerLoop를 continue합니다.
i: 0, j: 4
outerLoop를 continue합니다.
i: 2, j: 0
i: 2, j: 1
i: 2, j: 2
innerLoop를 continue합니다.
i: 2, j: 4
i: 3, j: 0
i: 3, j: 1
i: 3, j: 2
innerLoop를 continue합니다.
i: 3, j: 4
outerLoop를 break합니다.