앱 개발 입문자를 위한 Dart 기본 문법 완전 정리
지난 포스팅에서 Dart가 어떤 언어인지, 그리고 Flutter가 어떤 프레임워크인지 알아보았습니다. Dart의 장점은 앱 개발 초보자도 어렵지 않게 문법을 익힐 수 있다는 것과 자바(Java) 경험자라면 더 빠르게 익숙해진다는 점입니다.
또한 설치 없이 웹에서 바로 실행 가능한 DartPad(https://dartpad.dev) 를 제공하여 누구나 쉽게 실습할 수 있습니다.
이번 실습은 모두 DartPad 에서 진행합니다.

DartPad로 실습 준비 (설치 없이 바로 실습하는 방법)
DartPad는 웹 브라우저에서 Dart 코드를 바로 실행할 수 있는 공식 도구입니다.
https://dartpad.dev
브라우저에서 들어가면 바로 에디터 + 실행 버튼이 나타납니다.
아래 초기 예제처럼 코드를 편집하고 Run ▶(혹은 Ctrl + Enter)을 눌러 실행하면 됩니다.
void main() {
print('Hello Dart!');
}
기본 문법 정리
이제부터 Dart 의 기본 문법에 대해 정리하고 실습을 원활하게 할 수 있도록 예문 코드를 함께 제공합니다. 포스팅을 보시면서 함께 따라하시면 훨씬 빠른 성취가 가능합니다. 지금부터 시작 할 테니 천천히 따라하시면서 이해하시면 되겠습니다
✔ main() 함수
Dart 프로그램의 시작점은 항상 main() 입니다.
void main() {
print('반갑습니다. 제로입니다!');
}
Java와 비교하면 Java의 public static void main(String[] args) 에서 System.out.print(); 에 해당합니다.
C언어와 비교하면 int main() 에서 printf(); 에 해당합니다.
Python과 비교하면 시작점은 따로 없지만 출력문은 print() 와 같습니다.
C#과 비교하면 static void main() 에서 Console.WriteLine(); 과 같습니다.
Java가 궁금하다면? [Java] Java에 대해 알아보자.(Java 시리즈 1편)
C언어가 궁금하다면? [C언어] C언어에 대해 알아보자.(C언어 시리즈 1편)
Python이 궁금하다면? [파이썬] 파이썬에 대해 알아보자(파이썬 시리즈 1편)
C#이 궁금하다면? [C#] C#에 대해 알아보자 (C# 시리즈 1편)
✔ var (타입 자동 추론)
var name = 'ZeroToDev';
var age = 28;
자동으로 변수의 타입이 결정됩니다.
JavaScript와 동일합니다.
✔ 명시적 타입 선언
String title = '앱개발';
int count = 10;
double score = 3.14;
bool isOpen = true;
변수의 타입을 명시하는 방법은 다른 언어들과 똑같습니다.
문자열은 String / 정수형은 int / 소수는 double / 참거짓은 bool 을 사용합니다.
✔ final / const (불변 변수)
이 부분이 약간 Java와 비슷한 느낌을 갖는 것 중에 하나였습니다. 변수가 불변하도록 지정해주는 선언입니다.
- final : 한 번만 값 할당 가능 (런타임에 결정)
- const : 컴파일 시점에 값이 확정되어야 함
final today = DateTime.now(); // OK
const pi = 3.141592; // OK
// const today2 = DateTime.now(); // ❌ 오류
✔ Java와 비교하면?
| 개념 | Dart | Java |
|---|---|---|
| 타입 자동 추론 | var | var (Java 10+) |
| 불변 변수 | final, const | final |
| 기본 타입 | int, double, bool, String | int, double, boolean, String |
✔ 문자열(String)과 문자열 보간
문자열을 쉽게 합칠 수 있습니다.
var name = "홍길동";
print("안녕하세요 $name 님");
print("2 + 3 = ${2 + 3}");
Java에는 $name 스타일이 없고 + 또는 printf를 이용해야 하는 차이가 있습니다.
✔ 리스트(List)
var items = [1, 2, 3];
items.add(4);
print(items); // [1, 2, 3, 4]
✔ 타입 지정 리스트
List<String> names = ['kim', 'lee'];
✔ 맵(Map)
Key-Value 구조를 가집니다. 이 점 염두에 두고 봐주세요.
var user = {
'name': '철수',
'age': 20,
};
print(user['name']);
✔ Java와 비교
| Dart | Java |
|---|---|
| List는 기본 제공 | ArrayList import 필요 |
| Map도 기본 제공 | HashMap import 필요 |
| 문법 간단 | 문법 길고 타입 명시 길어짐 |
✔ if문
int age = 20;
if (age >= 20) {
print('성인');
} else {
print('미성년자');
}
if 라는 구문은 프로그래밍에서도 조건을 제시하기 위해 사용되지만 컴퓨터활용능력에서 사용되는 엑셀 함수에서도 if 문이 조건문으로 사용됩니다. 즉, if는 대표적인 조건문의 예시라고 생각하시면 편합니다.
if문의 구성은 다음과 같습니다.
먼저 if 문에 ( )로 조건을 제시합니다. 위 소스코드를 예시로 본다면 먼저 정수형 변수 age를 20이라는 값으로 선언했습니다.
그래서 age >= 20 // age 가 20보다 크거나 같은가? 라고 조건을 제시합니다.
그리고 print(‘성인’); // 20보다 크거나 같으면 ‘성인’ 이라고 출력하라 라는 뜻이 됩니다.
else는 쉽게 말하면 if의 조건이 거짓이라면? 입니다. 우리가 영어회화에서 주문 후에 anything else? 라고 더 필요한게 없냐고 묻는 것 처럼. if의 조건이 (20보다 크거나 같으면) 참이면 성인. 그렇다면? else? 참이 아니면? 뭐라고 해? 라고 묻는거죠. if와는 다르게 조건을 따로 제시하지 않습니다. else에는 ~if 라는 뜻이기 때문입니다.
즉, 20보다 크거나 같다 가 아니라면? -> 20보다 작으면? -> 20 미만(age < 20) 이면?이라는 말이 함축되어 있습니다.
그 경우 어떻게 하느냐 라는 내용은 print(‘미성년자’); 라고 적혀있습니다.
최종적으로 정리해보자면 age 가 20이상(크거나 같다) 이면 ‘성인’ 그렇지 않으면 미성년자 라고 출력하라. 라는 뜻입니다.
✔ switch문
var grade = 'A';
switch (grade) {
case 'A':
print('우수');
break;
case 'B':
print('보통');
break;
default:
print('기타');
}
Java와 거의 동일합니다. Java 입문 혹은 초급 개발자의 경우에는 쉽게 익히실 겁니다.
입문으로 처음 접하신 분은 해당 소스코드를 천천히 입력해보면서 실시간으로 우측의 결과 값을 봐주시면 이해가 빠르실 겁니다.
먼저 변수로 grade 를 ‘A’ 라고 선언했습니다. 타입을 var 라고 한 것을 보니 따로 형태를 지정하지 않은 변수입니다.
이후 switch(grade) 로 switch 문을 생성합니다. grade의 값을 받아와서 여기 switch 문에 넣어라 가 됩니다.
case ‘A’ :
print(‘우수’);
break;
grade의 값이 A라는 값을 가지는 경우라면(그런 케이스라면)?
print(‘우수’); // ‘우수’ 라는 값을 출력하라.
break; // 멈추고 switch 문을 빠져나가라. (* break 가 없으면 다음 구문을 연달아 실행하는 것이 됩니다. 이 부분을 명심하셔야 합니다.)
case ‘B’ :
print(‘보통’);
break;
grade 의 값이 B라는 값을 가지는 경우라면(그런 케이스라면)?
print(‘보통’); // ‘보통’ 이라는 값을 출력하라.
break; // 멈추고 switch 문을 빠져나가라.(* break 가 없으면 다음 구문을 연달아 실행하는 것이 됩니다. 이 부분을 명심하셔야 합니다.)
default :
print(‘기타’);
grade 의 값이 A , B 케이스에도 해당하지 않는다면?
print(‘기타’); // ‘기타’ 를 출력하고 switch 문을 종료한다.(* default 값이기 때문입니다!)
이러한 구조로 작동하는 구문입니다. 한번 글을 읽어보시고 실습해 보시면 이해가 빠르실 겁니다.
✔ for문
for (int i = 0; i < 5; i++) {
print(i);
}
입문자 분들을 위한 설명입니다. for문은 대표적인 반복문으로 for 라는 구문 안에 3가지의 기준을 부여합니다.
위 소스코드를 토대로 해석하자면
int i = 0;
먼저 i 라는 변수의 변수 타입을 정수형인 int로 부여하고 i의 값을 0으로 초기화 해줍니다.
i<5;
i라는 변수의 값이 5미만 일 때 까지 반복하라. 라는 뜻입니다.
i++;
i라는 변수의 값을 1만큼 증가시켜라. 라는 뜻입니다.
이제 이 구조를 이해했으니 전체적으로 for 문을 봅시다. 해당 조건이 수행되면서 print(i); i의 값을 출력하라 라는 뜻입니다.
그렇다면 이 값은
0
1
2
3
4
가 됩니다.
* 이런 것을 개행 이라고 합니다. 기본적으로 print 구문은 줄바꿈(개행)을 수행합니다.
* 개행 없이 옆으로 연달아 쓰고 싶으신 분 >> 방법이 있기는 하지만 DartPad 에서는 지원되지 않습니다. 실제 사용할 때는 Import ‘dart:io’; 를 먼저 선언해서 임포트 해준 후에 print(i); 대신 stdout.write(i); 를 사용하면 됩니다.
✔ for-in 문
var list = ['a', 'b', 'c'];
for (var item in list) {
print(item);
}
for in 의 경우 Java의 enhanced for문과 동일합니다.
입문자를 위해 코드를 설명해 보겠습니다.
var list = [‘a’, ‘b’, ‘c’]; 로 리스트 ‘a’ , ‘b’ , ‘c’ 를 선언합니다.
for 구문 안에 (var item in list) 로 선언해서 list에 있는 값을 item 이라는 통 안에 넣어준다고 생각하시면 됩니다.
print(item); 으로 item을 출력하라. 라는 뜻이 됩니다.
그러면 이 결과값은
a
b
c
가 됩니다.
✔ while문
int n = 3;
while (n > 0) {
print(n);
n--;
}
while 문도 대표적인 반복문입니다. for 문은 변수를 지정해서 조건을 지정하고 증가량 등을 지정했다면 while은 변수에 조건을 걸어 준 후 내부 구문으로 다른 조건을 걸어줍니다.
위 소스코드를 주제로 해설하면
int n = 3; // 정수형 타입 변수 n에 3이라는 값으로 선언합니다.
while(n>0) // n이 0보다 크다면 이 while문을 수행하라.
print(n); // n의 값을 출력하라.
n–; // n의 값에서 1만큼 감소시켜라.
라는 뜻이 됩니다. 위의 n의 값이 3이므로.
첫번째 수행 : 3은 0보다 큰 값입니다. 고로 while 문을 수행합니다. // 출력값 3 // 1만큼 감소시킵니다. n의 값은 2가 됩니다.
두번째 수행 : 2는 0보다 큰 값입니다. 고로 while 문을 수행합니다. // 출력값 2 // 1만큼 감소시킵니다. n의 값은 1이 됩니다.
세번째 수행 : 1은 0보다 큰 값입니다. 고로 while 문을 수행합니다. // 출력값 1 // 1만큼 감소시킵니다. n의 값은 0이 됩니다.
네번째 -> 0은 while 문의 조건인 0보다 크지 않습니다. 고로 while 문을 수행하지 않습니다.
결과값은
3
2
1
이 됩니다.
✔ 기본 함수
void greet(String name) {
print("Hello $name");
}
✔ 반환값이 있는 함수
int add(int a, int b) {
return a + b;
}
✔ 화살표 함수(람다)
int multiply(int x, int y) => x * y;
Java보다 훨씬 간결합니다.
✔ 기본 클래스
class Person {
String name;
int age;
Person(this.name, this.age);
void sayHello() {
print("안녕하세요. 저는 $name 입니다.");
}
}
✔ 사용
void main() {
var p = Person("홍길동", 20);
p.sayHello();
}
✔ Java와의 차이점
| 개념 | Dart | Java |
|---|---|---|
| 생성자 | Person(this.name) | Person(String name) |
| new 키워드 | optional | new 필수 |
| null safety | 기본 내장 | Java는 Optional 사용 |
Java에 비해 문법이 훨씬 간결한 걸 알 수 있습니다.
Dart Null-safety (중요)
Dart는 null로 인한 오류를 막기 위해 타입 뒤에 ?를 붙여 nullable로 표시해야 합니다.
String? name; // null 가능
name = null; // OK
Java에는 이런 기능이 없어 NPE(Null Pointer Exception) 발생 가능성이 높습니다. 하지만 다트는 해당 기능으로 오류 관리에 굉장히 유연하게 대처가 가능합니다.
DartPad 실습용 완성 코드
이번에는 여러분들이 통합적으로 실습할 수 있도록 준비한 완성 예제 코드입니다.
아래 코드를 DartPad에 그대로 붙여 넣어 실행하면 핵심 문법을 한 번에 복습할 수 있습니다.
(저는 붙여넣기 보다 따라 타이핑 하시는 것을 추천합니다. 코딩은 쳐보는게 훨씬 유익합니다)
void main() {
// 변수
var name = "ZeroToDev";
int age = 30;
print("이름: $name, 나이: $age");
// 리스트
List<String> items = ["Dart", "Java", "Flutter"];
for (var item in items) {
print("아이템: $item");
}
// 맵
var user = {"name": "홍길동", "age": 25};
print("사용자 이름: ${user['name']}");
// 조건문
if (age > 20) print("성인입니다.");
// 함수 사용
print("2 + 3 = ${add(2, 3)}");
// 클래스 사용
var p = Person("철수", 22);
p.sayHello();
}
// 함수
int add(int a, int b) => a + b;
// 클래스
class Person {
String name;
int age;
Person(this.name, this.age);
void sayHello() => print("안녕하세요! 저는 $name 입니다.");
}
정리 – Dart 문법을 배우면 Flutter가 쉬워진다
Dart는 Java보다 문법이 간결하면서 객체지향 특성은 그대로 유지하는 언어입니다. 따라서 Java 경험자는 쉽게 적응하고, 프로그래밍 입문자도 부담 없이 시작할 수 있습니다.
Dart 문법을 익히면 Flutter UI와 로직이 훨씬 이해하기 쉬워지므로 이번 포스팅 내용은 반드시 확실히 익혀두는 것이 좋습니다.
다음 편 예고
다음 글에서는 Flutter 실전 입문으로 들어갑니다.
[앱개발] 4. Flutter 입문 – 화면 구성과 위젯 구조 완전 이해하기
✔ 위젯이란?
✔ Stateful / Stateless
✔ Scaffold · AppBar 만들기
✔ 버튼 / 텍스트 / 컬럼 / 로우 배치
✔ Flutter 첫 화면 만들기 실습
이제 본격적인 앱 화면을 만드는 단계로 넘어가겠습니다!