
예외, 오류, 라이브러리
/// 별 피라미드 출력 하기
void main() {
// *
// ***
// *****
// *******
// **********
// ************
// **************
// ****************
// int star = 1;
// print(" ${"*" * star}");
// star = star + 2; // => 3
// print(" ${"*" * star}");
// star = star + 2; // => 3+2 = 5
// print(" ${"*" * star}");
// star = star + 2; // => 5+2 = 7
// print(" ${"*" * star}");
// star = star + 2; // => 7+2 = 9
// print(" ${"*" * star}");
// star = star + 2; // => 9+2 = 11
// print(" ${"*" * star}");
// star = star + 2; // => 11+2 = 13
// print(" ${"*" * star}");
// star = star + 2; // => 13+2 = 15
// print(" ${"*" * star}");
int star = 1;
for (var i = 0; i <= 7; i++) {
// 1단 => 별 1개
// 2단 => 별 3개
// 3단 => 별 5개...
// 별이 2씩 증가
String space = ' ' * (7 - i);
// 여기서 별 출력
// 공백 => -1씩 빼는거 : Strint 7-"i"
print(space + '*' * star);
star = star + 2; // => star 15
}
// 별이 반대로 감소 하는 걸로 만듬
for (var i = 1; i <= 7; i++) {
int spaceCount = i + 0;
star = star - 2; // => star 13
// print("공백 : $spaceCount 현재별개수 : $star"); => 공백 1 => 1++
print(' ' * spaceCount + '*' * star);
}
}
void main() {
// 2는 고정
// 곱해지는 수가 1씩 증가
// 첫번째 단계 : 1부터 9까지 반복문으로 출력하기
// 두번째 미션 : 2단부터 9단까지 출력
for (var i = 1; i <= 9; i++) {
print('2 * $i = ${2 * i} ');
}
// print(' 2 * 1 = 2 ');
// print(' 2 * 2 = 4 ');
// print(' 2 * 3 = 6 ');
// print(' 2 * 4 = 8 ');
// print(' 2 * 5 = 10 ');
// print(' 2 * 6 = 12 ');
// print(' 2 * 7 = 14 ');
// print(' 2 * 8 = 16 ');
// print(' 2 * 9 = 18 ');
}
Exception 클래스를 상속받아서 구성됨Exception 클래스의 하위 클래스임Exception 클래스를 상속받은 클래스로 객체를 생성해주는것이 좋음-필요한 시점에 로드되도록 설정한 라이브러리가 로드되지 못 했을 때 발생
DeferredLoadException(String message)
message 에 예외에 대한 설명을 써주면 돼요.
FormatException([String message = "", dynamic source, int? offset])
message : 예외에 대한 설명
source : 예외가 발생한 원인이 되는 것
HttpExceptionProcessExceptionSignalExceptionSocketExceptionStdinExceptionStdoutExceptionTlsExceptionWebSocketExceptionOSError([String message = "", int errorCode = noErrorCode])
message 에는 운영체제가 제공하는 예외에 대한 설명이 들어가요.
운영체제가 설명을 제공하지 않으면 빈 문자열 (””) 이 적용돼요.
errorCode 에는 운영체제가 제공하는 오류 코드가 들어가요.
TimeoutException(String? message, [Duration? duration])
message 에는 시간 초과가 발생한 원인에 대한 설명이 들어가고,
duration 에는 초과된 시간이 들어가요.
Exception 클래스를 상속 받아서 새로운 예외 클래스를 만들수 있음class AgeException implements Exception {
final String message;
AgeException(this.message);
}
상속 받을 때 implements 키워드를 사용한다고 했던 것 기억하죠 ~?
class AgeException implements Exception {
final String? message;
AgeException(this.message);
String toString() => message ?? 'AgeException 이 발생했어요 !';
}
예외 클래스도 당연히 를 통해 재정의할 수 있어요 👍🏼
상속 받은 후에 를 통해 재정의할 수 있다고 했던 것 기억하죠 ~?
class AgeException implements Exception {
final String? message;
AgeException(this.message);
}
void printAge(int age) {
if (age < 0) {
throw AgeException(null);
}
print(age);
}
void main() {
try {
printAge(-8);
} catch (e) {
print(e);
}
}
printAge() 의 매개변수에 음수값을 전달했기 때문에
Instance of 'AgeException’ 이 출력돼요.
class AgeException implements Exception {
final String? message;
AgeException(this.message);
}
void printAge(int age) {
if (age < 0) {
throw AgeException(null);
}
print(age);
}
void main() {
try {
printAge(8);
} catch (e) {
print(e);
}
}
printAge() 의 매개변수에 0 이상의 값을 전달했기 때문에 8 만 출력돼요.
class AgeException implements Exception {
final String? message;
AgeException(this.message);
String toString() => message ?? 'AgeException 이 발생했어요 !';
}
void printAge(int age) {
if (age < 0) {
throw AgeException(null);
}
print(age);
}
void main() {
try {
printAge(-8);
} catch (e) {
print(e);
}
}
printAge() 의 매개변수에 음수값을 전달했기 때문에
AgeException 이 발생했어요 ! 가 출력돼요.
class AgeException implements Exception {
final String? message;
AgeException(this.message);
String toString() => message ?? 'AgeException 이 발생했어요 !';
}
void printAge(int age) {
if (age < 0) {
throw AgeException('0 이상의 값을 넣어야 해요 !');
}
print(age);
}
void main() {
try {
printAge(-8);
} catch (e) {
print(e);
}
}
AgeException 의 생성자에 null 이 아닌 값을 넣어 주었기 때문에
0 이상의 값을 넣어야 해요 ! 가 출력돼요.
try 의 코드 블록 실행 중에 예외가 발생하면try 의 코드 블록에 있는 뒷 코드들은 실행되지 않아요.try {
// 예외가 발생할 수 있는 코드
}
try의 코드 블록 싱행 중에 예외가 발생했을 때 실행할 코드를 넣는 부분try의 코드 블록에서 예외가 발생하지 않으면 실행되지 않음catch (e) {
print(e);
}
발생한 예외의 객체가 catch 의 매개변수로 전달돼요.
try 의 코드 블록에서 발생할 수 있는 예외 중 특정 타입의 예외를 다루는 부분catch 와 항상 같이 써야함on IOException catch (e) {
// IOException 이 발생했을 때 실행할 코드
}
void main(){
try
String invalidNumber = "abc";
int result = int.parse(invalidNumber);
} catch (e) {
print(e);
}
}
on 으로 예외 타입을 특정해 주지 않으면
Exception 이 기본적으로 가지고 있는 4가지 요소만 사용할 수 있어요.
```dart
void main(){
try
String invalidNumber = "abc";
int result = int.parse(invalidNumber);
} on FormatException catch (e) {
print(e);
}
}
on 으로 예외 타입을 특정해 주면 그 타입이 가지고 있는 요소들을 사용할 수 있어요.
try,catch를 모두 거친 후 실행finally {
// 예외 처리 후 실행할 코드
}
try {
String invalidNumber = "abc";
int result = int.parse(invalidNumber);
print(result);
} catch (e) {
print(e);
}
e 에 FormatException 클래스의 객체가 전달돼서
FormatException: abc 라고 출력된답니다 !
try 의 코드 블록에 있는 int.parse(invalidNumber); 에서 예외가 발생했기 때문에
그 아래에 있는 print(result); 는 실행되지 않고, catch 문으로 넘어가요.
try {
String invalidNumber = "abc";
int result = int.parse(invalidNumber);
print(result);
} on FormatException catch (e) {
print(e);
}
마찬가지로 e 에 FormatException 클래스의 객체가 전달돼서
FormatException: abc 라고 출력돼요.
try {
String invalidNumber = "abc";
int result = int.parse(invalidNumber);
print(result);
} on FormatException catch (e) {
print(e);
} catch (e) {
print(e);
}
on FormatException catch (e) { … } 는 FormatException 이 발생하면 실행되고,
catch (e) { … } 는 FormatException 이 아닌 다른 예외가 발생하면 실행돼요.
try {
String invalidNumber = "abc";
int result = int.parse(invalidNumber);
print(result);
} catch (e) {
print(e);
} finally {
print('예외 처리 끝 -');
}
FormatException: abc 랑 예외 처리 끝 - 이 차례대로 출력되겠죠 ?
try {
String validNumber = "123";
int result = int.parse(validNumber);
print(result);
} catch (e) {
print(e);
} finally {
print('예외 처리 끝 -');
}
“123” 은 정수형으로 변환할 수 있기 때문에 예외가 발생하지 않아요.
그래서 result 값인 123 이랑 예외 처리 끝 - 이 차례대로 출력된답니다 !
Exception 클래스나 Error 클래스를 통해 생성한 객체를 던짐Exception 클래스나 Error 클래스를 상속 받은 클래스도 가능void printAge(int age) {
if (age < 0) {
throw Exception('나이는 0 이상이어야 해요 !');
}
print(age);
}
void main() {
try {
printAge(-8);
} catch (e) {
print(e);
}
}
printAge() 의 매개변수에 음수값을 전달하면 Exception 이 발생하기 때문에
Exception: 나이는 0 이상이어야 해요 ! 가 출력돼요.
try 의 코드 블록 실행 중에 Exception 이 발생했으니
print(age); 는 실행되지 않겠죠 ?
try, catch, on 으로 처리할 수 있음void printAge(int age) {
if (age < 0) {
throw Exception('나이는 0 이상이어야 해요 !');
}
print(age);
}
void main() {
try {
printAge(8);
} on Exception catch (e) {
print(e);
}
}
printAge() 의 매개변수에 0 이상의 값을 전달하면
Exception 이 발생하지 않기 때문에 print(age); 로 8 이 출력돼요.
Error크래스를 상속받아서 구성void checkAge(int age) {
assert(age > 0, 'Age must be positive');
}
void main() {
checkAge(-5); // AssertionError 발생
}
checkAge() 의 매개변수에 -5 를 전달하면
assert() 의 매개변수에 있는 조건문이 거짓이 되기 때문에
AssertionError 가 발생하겠죠 ?
assert(text != null);
text 가 null 이면 AssertionError 가 발생하겠죠 ?
assert(number < 100);
number 가 100 이상이면 AssertionError 가 발생하겠죠 ?
assert(urlString.startsWith('https'));
urlString 이 ‘https’ 로 시작하지 않으면
AssertionError 가 발생하겠죠 ?
참고로, startsWith() 는 문자열이 특정 값으로 시작하는지 판별하는 함수랍니다 !
assert(number < 100, '100 이상이면 안 돼요 !');
조건문이 거짓이면 조건문 옆에 있는 메시지가 출력돼요.
ArgumentError클래스를 상속 받은 클래스var numbers = [1, 2, 3];
print(numbers[3]);
numbers 는 요소의 개수가 3 이기 때문에 Index 가 3 인 요소는 있을 수 없겠죠 ?
그래서 RangeError 가 발생한답니다 😅
index를 사용했을 때 발생RangError클래스를 상속 받은 클래스var numbers = [1, 2, 3];
print(numbers[-1]);
print(numbers[5]);
Index 는 0 이상의 정수만 가능하다고 했던 것 기억하시나요 ? 🧐
그래서 Index 에 음수를 넣으면 IndexError 가 발생해요.
Dart가 정의한 오류가 별로라 커스텀 할 때Error클래스를 상속받아서 새로운 오류 클래스를 만들면 됨class AgeError extends Error {
final String message;
AgeError(this.message);
}
class AgeError extends Error {
final String? message;
AgeError(this.message);
String toString() => message ?? 'AgeError 가 발생했어요 !';
}
@override 를 통해 재정의할 수 있어요 👍🏼@override 를 통해 재정의할 수 있다고 했던 것 기억하죠 ~?try-catch 를 통해 처리할 수 있다.Dart SDK 표준 라이브러리라고 부름Dart 프로그램에 포함되어 있어서 따로 import 해주지 않아도 됨Future, Stream 과 같은 클래스를 통해 비동기 프로그래밍을 지원함dart:core에서 제공하지 않는 무거운 콜렉션 타입을 제공함queue, linked list, hashmap, binary treeNative platform의 타겟은 Mobile, Desktop Dart 가 C API를 사용할 수 있도록 하는 기능을 제공함JavaScript 로 컴파일되는 코드랍니다 !JavaScript 와 브라우저 API 를 상호운용할 수 있는 기능을 제공함HTML 요소들과 Web 기반 응용 프로그램 리소스들을 제공함Flutter 의 Cupertino 위젯에 쓰이는 기본 아이콘 에셋을 제공함OS 와 macOS 에서 사용하는 NSUserDefaults,Android 에서 사용하는 SharedPreferences 와 같은 역할iOS 와 Android 에서 사진 다루는 기능을 제공함Firebase 와 연동하는 작업할 때 필요한 핵심 기능을 제공함Firebase 인증 API 를 사용하기 위한 기능을 제공함iOS 와 Android 의 권한을 다루는 기능을 제공함Lint 규칙을 쉽게 적용할 수 있도록 해주는 기능을 제공함Lint : 오류가 발생할 수 있는 코드, 코드 스타일에 어긋난 코드, 비효율적이거나 불필요한 코드 등을 찾아내서 경고를 띄워주는 도구SVG 를 렌더링하기 위한 기능을 제공함import 'dart:html';
Dart 에서 제공하는 html 을 가져온다는 뜻 !
import 'package:http/http.dart'
http 패키지를 가져온다는 뜻 !
보통 pub.dev 에 있는 외부 라이브러리를 가져올 때 package: 접두사가 붙어요.
import 'package:http/http.dart' as http;
package:http/http.dart 는 http 라는 별명이 생긴 것이랍니다 !
import 'package:lib1/lib1.dart' show foo;
package:lib1/lib1.dart 에서 foo 만 가져온다는 뜻 !
import 'package:lib2/lib2.dart' hide foo;
package:lib2/lib2.dart 에서 foo 를 제외하고 가져온다는 뜻 !
import 'package:greetings/hello.dart' deferred as hello;
import 'package:greetings/hello.dart' deferred as hello;
Future<void> greet() async {
await hello.loadLibrary();
hello.printGreeting();
}
참고로, await 는 실행이 끝날 때까지 다음 작업을 못 하도록 해요.
그럼 await hello.loadLibrary(); 때문에
라이브러리가 로드될 때까지 멈춰 있겠죠 ?