다음 중 하나를 사용하여 Dart 코드의 흐름을 제어 할 수 있습니다.
if
와 else
for
반복문white
과 do-while
반복문break
과 continue
switch
와 case
문assert
예외에 설명 된대로 try-catch
및 throw
를 사용하여 흐름제어에 영향을 줄 수도 있습니다.
Dart는 아래 샘플에서 볼 수 있듯이 선택적 else
문이있는 if
문을 지원합니다. 조건식도 참조하십시오.
if (isRaining()) {
you.bringRainCoat();
} else if (isSnowing()) {
you.wearJacket();
} else {
car.putTopDown();
}
JavaScript와 달리 조건식은 부울 값을 사용해야합니다. 자세한 내용은 부울을 참조하십시오.
일반적인 for
문으로 반복할 수 있습니다. 예시를 들면
var message = StringBuffer('Dart is fun');
for (var i = 0; i < 5; i++) {
message.write('!');
}
Dart for
문 내부의 클로저는 인덱스의 가치를 포착하여 Javascript에서 발견되는 일반적인 함정을 피합니다. 예를 들어 다음을 고려하십시오.
var callbacks = [];
for (var i = 0; i < 2; i++) {
callbacks.add(() => print(i));
}
callbacks.forEach((c) => c());
예상대로 출력은 0과 1입니다. 반대로 이 예제는 Javascript에서 2를 인쇄 한 다음 2를 인쇄합니다.
반복하는 객체가 Iterable이면 forEach()
메서드를 사용할 수 있습니다. 현재 반복 카운터를 알 필요가 없는 경우 forEach()
를 사용하는 것이 좋습니다.
candidates.forEach((candidate) => candidate.interview());
List 및 Set과 같은 반복 가능한 클래스는 for-in
형식의 반복도 지원합니다.
var collection = [1, 2, 3];
for (var x in collection) {
print(x); // 1 2 3
}
while
문은 반복 이전에 조건을 평가합니다.
while (!isDone()) {
doSomething();
}
do-while
문는 반복 이후에 조건을 평가합니다.
do {
printLine();
} while (!atEndOfPage());
반복을 중지하려면 break
를 사용합니다.
while (true) {
if (shutDownRequested()) break;
processIncomingRequests();
}
다음 반복으로 건너 뛰려면 continue
를 사용하십시오.
for (int i = 0; i < candidates.length; i++) {
var candidate = candidates[i];
if (candidate.yearsExperience < 5) {
continue;
}
candidate.interview();
}
List 또는 Set와 같은 Iterable을 사용하는 경우, 이 예제를 다르게 작성할 수 있습니다.
candidates
.where((c) => c.yearsExperience >= 5)
.forEach((c) => c.interview());
Dart의 switch
문은 ==
를 사용하여 정수, 문자열 또는 컴파일 시간 상수를 비교합니다. 비교 된 객체는 모두 동일한 클래스의 인스턴스 여야하며 (하위 유형이 아님) 클래스가 ==
를 재정의해서는 안됩니다. 열거 형은 switch
문에서 잘 작동합니다.
Dart의 Switch 문은 통역사 또는 스캐너와 같은 제한된 상황을위한 것입니다.
비어 있지 않은 각 case
문은 일반적으로 break
문으로 끝납니다. 비어 있지 않은 case
문을 종료하는 다른 유효한 방법은 continue
, throw
또는 return
문입니다.
case
문이 일치하지 않을 때 default
문을 사용하여 코드를 실행합니다.
var command = 'OPEN';
switch (command) {
case 'CLOSED':
executeClosed();
break;
case 'PENDING':
executePending();
break;
case 'APPROVED':
executeApproved();
break;
case 'DENIED':
executeDenied();
break;
case 'OPEN':
executeOpen();
break;
default:
executeUnknown();
}
다음 예시에서는 case
절에서 break
문을 생략하여 오류를 생성합니다.
var command = 'OPEN';
switch (command) {
case 'OPEN':
executeOpen();
// ERROR: Missing break
case 'CLOSED':
executeClosed();
break;
}
그러나 Dart는 빈 case
문을 지원하여 다음과 같은 폴 스루 형식을 허용합니다.
var command = 'CLOSED';
switch (command) {
case 'CLOSED': // Empty case falls through.
case 'NOW_CLOSED':
// Runs for both CLOSED and NOW_CLOSED.
executeNowClosed();
break;
}
정말로 폴 스루를 원한다면 continue
문과 레이블을 사용할 수 있습니다.
var command = 'CLOSED';
switch (command) {
case 'CLOSED':
executeClosed();
continue nowClosed;
// Continues executing at the nowClosed label.
nowClosed:
case 'NOW_CLOSED':
// Runs for both CLOSED and NOW_CLOSED.
executeNowClosed();
break;
}
case
문에는 해당 문의 범위 내에서만 볼 수 있는 지역 변수가 있을 수 있습니다.
개발 중에는 assert
문을 사용하십시오 — assert (condition, optionalMessage);
— 부울 조건이 거짓 인 경우 정상적인 실행을 방해합니다. 이 둘러보기를 통해 assert
문 예제를 찾을 수 있습니다. 다음은 몇 가지 더 있습니다.
// 변수에 null이 아닌 값이 있는지 확인하십시오.
assert(text != null);
// 변수가 100보다 작은지 확인하십시오.
assert(number < 100);
// https URL인지 확인하십시오.
assert(urlString.startsWith('https'));
assert
에 메시지를 첨부하려면 assert
할 두 번째 인수로 문자열을 추가합니다.
assert(urlString.startsWith('https'),
'URL ($urlString) should start with "https".');
주장 할 첫 번째 인수는 부울 값으로 확인되는 모든 표현식이 될 수 있습니다. 식의 값이true
이면 Assertion이 성공하고 실행이 계속됩니다. false
이면 Assertion이 실패하고 예외 (AssertionError)가 발생합니다.
Assertion은 정확히 언제 작동합니까? 사용중인 도구와 프레임 워크에 따라 다릅니다.
--enable-asserts
를 통해 Assertion을 지원합니다.프로덕션 코드에서는 Assertion이 무시되고 Assertion 할 인수가 평가되지 않습니다.
Dart 코드는 예외를 발생시키고 포착 할 수 있습니다. 예외는 예기치 않은 일이 발생했음을 나타내는 오류입니다. 예외가 포착되지 않으면 예외를 발생시킨 격리가 일시 중지되고 일반적으로 격리와 해당 프로그램이 종료됩니다.
Java와 달리 Dart의 모든 예외는 확인되지 않은 예외입니다. 메서드는 throw
할 수있는 예외를 선언하지 않으며 예외를 포착 할 필요가 없습니다.
Dart는 Exception 및 Error 유형은 물론 사전 정의 된 수많은 하위 유형을 제공합니다. 물론 자신 만의 예외를 정의 할 수 있습니다. 그러나 Dart 프로그램은 Exception 및 Error 개체뿐만 아니라 null
이 아닌 개체를 예외로 throw
할 수 있습니다.
다음은 예외를 던지거나 발생시키는 예시입니다.
throw FormatException('Expected at least 1 section');
throw 'Out of llamas!'; // 임의의 객체를 던질 수도 있습니다.
프로덕션 품질 코드는 일반적으로 오류 또는 예외를 구현하는 유형을 발생시킵니다.
예외를 던지는 것은 표현식이므로 =>
문은 물론 표현식을 허용하는 다른 모든 곳에서 예외를 던질 수 있습니다.
void distanceTo(Point other) => throw UnimplementedError();
예외를 포착나 캡처하면 예외가 전파되는 것을 중지합니다 (예외를 다시 던지지 않는 한). 예외를 포착하면 처리 할 수있는 기회가 제공됩니다.
try {
breedMoreLlamas();
} on OutOfLlamasException {
buyMoreLlamas();
}
둘 이상의 예외 유형을 발생시킬 수있는 코드를 처리하기 위해 여러 catch
절을 지정할 수 있습니다. throw
된 객체의 유형과 일치하는 첫 번째 catch
절이 예외를 처리합니다. catch
절이 유형을 지정하지 않으면 해당 절은 모든 유형의 throw 된 객체를 처리 할 수 있습니다.
try {
breedMoreLlamas();
} on OutOfLlamasException {
// A specific exception
buyMoreLlamas();
} on Exception catch (e) {
// Anything else that is an exception
print('Unknown exception: $e');
} catch (e) {
// No specified type, handles all
print('Something really unknown: $e');
}
앞의 코드에서 볼 수 있듯이 on
, catch
또는 둘 다를 사용할 수 있습니다. 예외 유형을 지정해야 할 때 on
을 사용하십시오. 예외 처리기에 예외 개체가 필요한 경우 catch
를 사용합니다.
catch()
에 하나 또는 두 개의 매개 변수를 지정할 수 있습니다. 첫 번째는 throw
된 예외이고 두 번째는 스택 추적 (StackTrace 객체)입니다.
try {
// ···
} on Exception catch (e) {
print('Exception details:\n $e');
} catch (e, s) {
print('Exception details:\n $e');
print('Stack trace:\n $s');
}
예외를 부분적으로 처리하고 전파를 허용하려면 rethrow
키워드를 사용하십시오.
void misbehave() {
try {
dynamic foo = true;
print(foo++); // 런타임 에러
} catch (e) {
print('misbehave() partially handled ${e.runtimeType}.');
rethrow; // 에러의 전파 허용
}
}
void main() {
try {
misbehave(); // 에러 전파로 인한 에러 발생
} catch (e) {
print('main() finished handling ${e.runtimeType}.');
}
}
예외 발생 여부에 관계없이 일부 코드가 실행되도록하려면 finally
절을 사용하십시오. 예외와 일치하는 catch
절이 없으면 finally
절이 실행 된 후 예외가 전파됩니다.
`try {
breedMoreLlamas();
} finally {
// Always clean up, even if an exception is thrown.
cleanLlamaStalls();
}
finally
절은 일치하는 catch
절 이후에 실행됩니다.
try {
breedMoreLlamas();
} catch (e) {
print('Error: $e'); // Handle the exception first.
} finally {
cleanLlamaStalls(); // Then clean up.
}
라이브러리 둘러보기의 예외 섹션을 읽고 자세히 알아보세요.