본 글은 [Do it! 깡샘의 플러터&다트 프로그래밍] 의 내용을 발췌한 것입니다.
책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.
제어문은 프로그램의 실행 흐름을 제어하는 구문입니다. 보통 프로그래밍 언어에서 제공하는 if~else, for, while, do~while, break, continue, switch~case 등이 제어문이며, 다트를 비롯해 대부분 언어에서 비슷하게 동작합니다. 이 절에서는 프로그램의 실행 흐름에서 다른 언어와 차이 나는 부분만 살펴보겠습니다.
for 반복문에서 in 연산자
for 문은 어떤 구문을 반복해서 실행할 때 이용하며 반복해서 실행할 조건을 다음처럼 초기화; 조건; 증감 형태로 작성합니다.
main() {
var list = [10, 20, 30];
for(var i = 0; i < list.length; i++) {
print(list[i]);
}
}
그런데 이런 형태를 in 연산자를 사용해 간소화할 수 있습니다. for 문에 범위 연산자인 in을 사용하면 오른쪽에 명시한 컬렉션 타입의 데이터 개수만큼 반복해서 실행합니다. 다음 코드에서 in 연산자는 for 문이 한 번 실행될 때마다 list의 데이터를 순서대로 가져와 x 변수에 대입합니다.
main() {
var list = [10, 20, 30];
for(var x in list) {
print(x);
}
}
switch~case 선택문
switch~case 구문은 if~else 구문과 더불어 조건에 따라 실행 흐름을 분기할 때 많이 사용합니다. 다트에서는 switch의 조건을 정수나 문자열 타입으로 지정할 수 있습니다. 또한 case가 여러 개라면 맨 마지막 case 문을 제외하고는 break, continue, return, throw 중 하나를 작성해 그다음 실행 흐름을 결정해 줘야 합니다.
•break: switch 문 나가기
•continue: 특정 위치(라벨)로 이동하기
•return: switch 문이 작성된 함수 종료하기(반환하기)
•throw: switch 문이 작성된 함수 종료하기(던지기)
예를 들어 다음 코드는 첫 번째 case 문에서 오류가 발생합니다.
some(arg) {
switch(arg) {
case 'A': // 오류
print('A');
case 'B':
print('B');
}
}
case 문을 2개 선언했는데 첫 번째 case 문에 break, continue, return, throw 등으로 그다음 실행 흐름을 지정하지 않아서 오류가 발생합니다. 따라서 다음처럼 작성해야 바르게 동작합니다.
some(arg) {
switch(arg) {
case 'A':
print('A');
break;
case 'B':
print('B');
}
}
예외 던지기와 예외 처리
예외 처리문은 대부분 언어에서 제공하는 런 타임 오류를 제어하는 구문이며 다트에서도 다른 언어와 비슷하게 예외 처리문을 제공합니다.
예외를 던지는 throw 문
프로그램이 실행되다 특정 시점에 예외를 발생시키고 싶다면 throw 문을 이용합니다. throw 오른쪽에는 객체를 작성하는데 다음 코드에서는 다트에서 예외를 표현하는 Exception 클래스를 작성했습니다.
some() {
throw Exception('my exception');
}
Exception 클래스 이외에 다른 객체를 던져도 됩니다. 다음처럼 문자열을 던질 수도 있습니다. throw 문이 실행되면 예외가 발생해 some() 함수를 호출한 곳에 해당 문자열을 던집니다.
some() {
throw 'my exception';
}
물론 다음처럼 개발자가 만든 객체를 던져도 됩니다.
class User{}
some() {
throw User();
}
try~on~finally 예외 처리
try~on~finally 구문은 예외 처리 조합입니다. try 문에 작성한 코드에서 예외가 발생하면 on 문이 실행되며, finally 문에는 예외와 상관없이 무조건 실행할 코드를 작성합니다. 다음코드는 try~on~finally 구문으로 예외를 처리하는 예이며 some() 함수를 호출할 때 예외가 발생합니다.
some() {
throw FormatException('my exception');
}
main(List<String> args) {
try {
print('step1....');
some();
print('step2....');
} on FormatException {
print('step3....');
} on Exception {
print('step4....');
} finally {
print('step5....');
}
print('step6....');
}
try 문에서 호출한 some() 함수에서 throw 문으로 예외를 던집니다. 따라서 some() 호출문 아래에 있는 구문은 실행되지 않고 실행 흐름은 on 문으로 넘어갑니다. on 문은 여러 개 정의할 수 있으며 on 오른쪽에는 처리할 예외의 종류, 즉 타입을 작성합니다. 그러면 예외가 발생할 때 해당 예외 타입에 맞는 on 문을 찾아서 실행합니다. 예제에서는 some() 함수에서 Format Exception 예외를 던지므로 on FormatException { } 구문이 실행됩니다.
만약 예외 처리문에서 어떤 예외가 발생했는지 알고자 한다면 catch 문으로 예외 객체를 받을 수 있습니다. on FormatException catch(e)라고 작성하면 발생한 예외 객체가 e에 전달됩니다.
some() {
throw FormatException('my exception');
}
main(List<String> args) {
try {
print('step1....');
some();
print('step2....');
} on FormatException catch(e) {
print('step3....$e');
} on Exception catch(e) {
print('step4....$e');
} finally {
print('step5....');
}
print('step6....');
}
만약 예외 종류를 구분하지 않겠다면 다음처럼 간단하게 작성할 수도 있습니다.
try {
some();
} catch(e) {
print('catch....$e');
}
책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.
'flutter' 카테고리의 다른 글
플러터 - factory constructor (0) | 2023.03.13 |
---|---|
플러터 - named constructor (0) | 2023.03.13 |
플러터 - named parameter (0) | 2023.03.13 |
플러터 - 컬렉션 타입 — List, Set, Map (2) | 2023.03.13 |
플러터 - var와 dynamic 타입 (0) | 2023.03.13 |