여기까지 왔습니다. 긴 여정이었지만, 돌아보면 생각보다 많은 것을 배웠습니다. 각 PART에서 만났던 핵심 개념들을 한데 모아 정리해봅니다.
PART별 핵심 개념 정리
PART 01. 개발 환경 준비하기
Dart SDK를 설치하고, VS Code에 확장 기능을 설정하고, DartPad로 브라우저에서 바로 코드를 실행해봤습니다. "Hello, Dart!"를 출력하는 그 첫 줄이 이 모든 여정의 시작이었습니다.
- Dart SDK 설치 및
dartCLI 명령어 사용 - VS Code + Dart 확장으로 개발 환경 구성
- DartPad로 설치 없이 Dart 코드 실행
dart run,dart compile기본 명령어
PART 02. 변수와 타입의 세계
변수를 선언하는 방법부터 Dart가 타입을 어떻게 다루는지 배웠습니다. var, final, const의 미묘한 차이, 그리고 null을 처음으로 마주쳤습니다.
var,final,const차이와 선택 기준- 기본 타입:
int,double,String,bool,dynamic - 타입 추론: 컴파일러가 타입을 알아서 결정
- null의 첫 만남과
?연산자 맛보기 - 산술, 비교, 논리, 할당 연산자 활용
PART 03. 흐름을 제어하다
프로그램이 "생각"하는 방식을 배웠습니다. 조건에 따라 다르게 행동하고, 반복하고, 함수로 기능을 묶는 법을 익혔습니다.
if/else,switch조건문으로 분기 처리for,while,do-while반복문 활용- 함수 선언과 반환값 다루기
- named 매개변수와 optional 매개변수로 유연한 함수 설계
=>화살표 함수로 간결하게 표현
PART 04. 여러 값을 다루다 — 컬렉션
하나의 값이 아닌 여러 값을 묶어서 다루는 법을 배웠습니다. List, Set, Map은 실전에서 가장 자주 쓰이는 도구입니다.
List: 순서 있는 데이터 목록Set: 중복 없는 고유한 값의 집합Map: 키-값 쌍으로 데이터 관리map(),where(),reduce()로 데이터를 함수형으로 처리- 스프레드 연산자(
...)로 컬렉션 합치기
PART 05. 객체로 생각하기 — 클래스와 OOP
현실 세계의 개념을 코드로 표현하는 객체 지향 프로그래밍을 배웠습니다. 클래스는 설계도이고, 객체는 그 설계도로 만든 실물입니다.
- 클래스 선언, 필드, 메서드,
this키워드 - 기본 생성자, named 생성자,
factory생성자 extends로 상속하고,super로 부모 접근abstract class로 공통 인터페이스 정의implements로 인터페이스 구현with으로 믹스인(mixin) 기능 조합enum으로 의미 있는 상수 집합 표현
PART 06. 안전한 코드의 비밀 — Null Safety 심화
Dart가 null 관련 버그를 컴파일 시점에 잡아내는 Sound Null Safety를 깊이 파고들었습니다. 처음엔 낯설지만, 익숙해지면 코드에 대한 자신감이 생깁니다.
- Sound Null Safety: nullable(
?)과 non-nullable 타입 구분 ?.null-aware 접근,??null 병합,??=null 병합 할당!null 단언 연산자와 남용 금지late키워드로 늦은 초기화 처리- 흐름 분석(Flow Analysis)으로 타입 자동 승격
PART 07. 타입을 자유롭게 — 제네릭
같은 로직을 다양한 타입에 재사용하는 제네릭을 배웠습니다. 타입 안전성을 유지하면서도 코드 중복을 줄이는 강력한 도구입니다.
<T>로 제네릭 클래스 선언하고 활용- 제네릭 함수로 타입에 구애받지 않는 유틸리티 작성
extends로 타입 매개변수에 제약 조건 추가extension으로 기존 타입에 메서드 추가(확장 메서드)
PART 08. 기다림의 미학 — 비동기 프로그래밍
네트워크 요청, 파일 읽기처럼 "기다려야 하는" 작업을 우아하게 처리하는 비동기 프로그래밍을 배웠습니다.
Future로 미래의 값을 표현async/await로 비동기 코드를 동기처럼 읽기 쉽게 작성Stream으로 연속적으로 흐르는 데이터 처리Isolate로 멀티스레딩과 병렬 처리try/catch/finally로 비동기 에러 안전하게 처리
PART 09. Dart 3의 새 얼굴 — 패턴과 레코드
Dart 3에서 새롭게 추가된 기능들을 배웠습니다. 함수형 스타일의 코드를 더 명확하고 간결하게 만들어주는 현대적인 문법입니다.
- 레코드(
(type, type))로 여러 값을 타입 안전하게 묶기 - 패턴 매칭으로 데이터 구조를 분해하고 검사
switch표현식으로 값을 반환하는 분기 처리- 구조 분해(Destructuring)로 List, Map, 객체에서 값 추출
sealed class로 완전한 타입 계층 정의
PART 10. 미니 프로젝트 — 할 일 관리 CLI 앱
배운 모든 것을 하나의 프로젝트로 엮어봤습니다. CLI에서 할 일을 추가하고, 완료하고, 삭제하고, JSON 파일에 저장하는 실전 앱을 만들었습니다.
- CLI 인자 파싱과 대화형 입력 처리
dart:convert로 JSON 직렬화/역직렬화dart:io로 파일 입출력 구현- OOP 설계:
Todo모델,TodoRepository,TodoHandler분리 - 예외 처리와 사용자 친화적 에러 메시지
학습 체크리스트
지금까지 배운 내용을 스스로 점검해봅니다. 자신 있게 "할 수 있다"고 답할 수 있는 항목이 늘어날수록 실력이 쌓인 것입니다.
기초 문법
-
var,final,const의 차이를 설명할 수 있다. - 기본 타입(
int,double,String,bool)을 상황에 맞게 사용할 수 있다. -
if/else,switch,for,while을 활용한 흐름 제어를 작성할 수 있다. - 함수를 선언하고, named 매개변수와 optional 매개변수를 활용할 수 있다.
- 화살표 함수(
=>)로 간결하게 표현할 수 있다.
컬렉션과 OOP
- List, Set, Map을 생성하고 데이터를 추가/조회/삭제할 수 있다.
-
map(),where(),reduce()를 활용해 데이터를 변환할 수 있다. - 클래스를 설계하고 생성자, 필드, 메서드를 구현할 수 있다.
- 상속(
extends)과 추상 클래스(abstract)를 적절히 활용할 수 있다. - 믹스인(
with)으로 기능을 조합할 수 있다.
Null Safety와 제네릭
- nullable 타입(
?)과 non-nullable 타입의 차이를 이해한다. -
?.,??,??=,!연산자를 상황에 맞게 사용할 수 있다. -
late키워드가 필요한 상황을 설명할 수 있다. - 제네릭 클래스와 제네릭 함수를 작성할 수 있다.
- 확장 메서드(
extension)로 기존 타입에 기능을 추가할 수 있다.
비동기와 Dart 3
-
Future와async/await를 활용해 비동기 코드를 작성할 수 있다. -
Stream을 구독하고 데이터를 처리할 수 있다. - 비동기 에러를
try/catch로 처리할 수 있다. - 레코드와 구조 분해를 활용해 여러 값을 다룰 수 있다.
-
switch표현식과 패턴 매칭으로 분기를 처리할 수 있다.
실전 응용
- 작은 CLI 앱을 설계하고 구현할 수 있다.
- JSON 파일에 데이터를 읽고 쓸 수 있다.
- 코드를 역할에 따라 클래스로 분리할 수 있다.
- 예외 상황을 예측하고 적절히 처리할 수 있다.
아직 체크하지 못한 항목이 있어도 괜찮습니다. 이 책을 한 번 읽었다고 모든 것이 머릿속에 남는 것은 아닙니다. 다시 돌아와서 해당 PART를 펼쳐보고, 직접 코드를 타이핑해보는 것이 가장 좋은 복습 방법입니다.