Dart는 구글이 개발한 언어로, 특히 Flutter 프레임워크와 함께 사용되며 웹, 모바일, 데스크톱 애플리케이션 개발에 주로 활용됩니다. Dart는 JavaScript 대체 언어로 출발했지만, 현재는 안정성과 성능을 모두 갖춘 고수준 언어로 자리 잡았습니다. 이 글에서는 Dart 문법을 이해하기 쉽게 설명하며 개발자 입장에서 알아두어야 할 핵심 개념을 다루겠습니다.
1. Dart의 기본 문법 – 시작하기
Dart는 기본적으로 Java와 C 스타일의 문법을 사용하므로, 다른 언어를 학습한 경험이 있다면 쉽게 접근할 수 있습니다. 먼저, Dart 언어의 기본 구조와 변수 선언 방식 등을 살펴보겠습니다.
1.1 기본 코드 구조
Dart는 void main()
함수에서 실행이 시작됩니다. 메인 함수는 프로그램의 시작점이며, 모든 Dart 프로그램은 반드시 이 함수를 포함해야 합니다.
void main() {
print("Hello, Dart!");
}
여기서 print()
함수는 콘솔에 출력을 하는 기본 함수입니다. 이 함수는 디버깅이나 단순한 출력을 위해 자주 사용됩니다.
1.2 변수와 데이터 타입
Dart는 강타입 언어로 변수의 타입을 명확히 지정해야 하지만, var
, dynamic
키워드를 통해 자동 타입 추론도 가능합니다.
- var: 컴파일러가 변수의 타입을 자동으로 추론합니다.
- dynamic: 타입을 미리 지정하지 않으며, 어떤 타입이든 담을 수 있는 변수입니다.
void main() {
var name = 'John'; // 문자열
int age = 30; // 정수형
double height = 5.9; // 실수형
bool isActive = true; // 불리언
dynamic anything = 'Hello'; // 초기에는 문자열
anything = 123; // 나중에 정수 할당 가능
}
Dart의 타입은 기본적으로 int
, double
, String
, bool
등이 있으며, var
키워드를 통해 타입을 생략할 수도 있습니다. 다만, dynamic
은 타입 체크를 하지 않아 런타임 오류가 발생할 수 있습니다.
2. 연산자와 제어문
2.1 연산자
Dart는 다양한 연산자를 제공하며, 산술, 비교, 논리 연산자 등을 지원합니다.
- 산술 연산자:
+
,-
,*
,/
,%
- 비교 연산자:
==
,!=
,>
,<
,>=
,<=
- 논리 연산자:
&&
,||
,!
void main() {
int a = 10;
int b = 20;
print(a + b); // 덧셈
print(a > b); // 비교
print(a != b && b > 15); // 논리 연산
}
2.2 제어문
Dart의 제어문은 다른 언어와 비슷하며, 조건문과 반복문을 제공합니다.
- if 문과 else 문: 조건에 따라 코드 실행을 분기합니다.
- for 문과 while 문: 반복 작업을 수행합니다.
void main() {
int score = 85;
if (score > 90) {
print("A학점");
} else if (score > 80) {
print("B학점");
} else {
print("C학점");
}
for (int i = 0; i < 5; i++) {
print(i); // 0부터 4까지 출력
}
}
3. 함수와 함수형 프로그래밍
Dart는 함수형 프로그래밍 스타일을 지원하며, 함수를 일급 객체로 취급합니다. 함수는 변수처럼 사용될 수 있으며, 고차 함수도 사용할 수 있습니다.
3.1 함수 선언
Dart에서 함수를 정의하는 방식은 void
나 특정 반환 타입을 명시하여 사용합니다.
void main() {
print(add(10, 20)); // 함수 호출
}
int add(int a, int b) {
return a + b;
}
3.2 화살표 함수
단일 표현식 함수는 =>
를 사용하여 간결하게 작성할 수 있습니다.
int square(int x) => x * x;
3.3 고차 함수
Dart는 함수를 매개변수로 받거나 반환할 수 있는 고차 함수를 지원합니다.
void main() {
Function multiplyBy2 = (int x) => x * 2;
print(applyFunction(10, multiplyBy2)); // 20 출력
}
int applyFunction(int value, Function func) {
return func(value);
}
4. 클래스와 객체 지향 프로그래밍
Dart는 객체 지향 프로그래밍(OOP) 언어로, 클래스를 통해 코드 구조를 체계화할 수 있습니다.
4.1 클래스 정의와 객체 생성
class Person {
String name;
int age;
// 생성자
Person(this.name, this.age);
void introduce() {
print("이름: $name, 나이: $age");
}
}
void main() {
Person p = Person("John", 30);
p.introduce(); // 이름: John, 나이: 30
}
4.2 상속과 메서드 오버라이딩
Dart는 상속을 통해 클래스의 기능을 확장할 수 있으며, 메서드를 재정의할 수 있습니다.
class Animal {
void sound() {
print("동물이 소리를 냅니다.");
}
}
class Dog extends Animal {
@override
void sound() {
print("멍멍");
}
}
void main() {
Dog d = Dog();
d.sound(); // 멍멍
}
5. 컬렉션 – List, Set, Map
Dart는 데이터 구조로 List
, Set
, Map
등을 제공합니다.
5.1 List
List
는 배열과 비슷하며, 순서가 있는 데이터 모음입니다.
void main() {
List<int> numbers = [1, 2, 3];
numbers.add(4);
print(numbers); // [1, 2, 3, 4]
}
5.2 Set
Set
은 중복이 없는 요소의 집합입니다.
void main() {
Set<String> fruits = {"apple", "banana", "apple"};
print(fruits); // {apple, banana}
}
5.3 Map
Map
은 키-값 쌍으로 구성된 데이터 구조입니다.
void main() {
Map<String, int> scores = {"Alice": 90, "Bob": 85};
print(scores["Alice"]); // 90
}
6. 비동기 프로그래밍
Dart는 비동기 프로그래밍을 위해 async
와 await
키워드를 제공합니다. 주로 API 호출이나 파일 입출력 같은 시간이 오래 걸리는 작업을 처리할 때 사용됩니다.
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 2)); // 2초 지연
return "Data loaded";
}
void main() async {
print("Start");
String data = await fetchData();
print(data);
print("End");
}
맺음말
Dart는 문법이 간결하면서도 유연하여 초보자부터 고급 개발자까지 활용하기 좋은 언어입니다. Flutter와 함께 사용하면 강력한 UI 개발 도구로 활용할 수 있어 모바일, 웹, 데스크톱 개발에 폭넓게 쓰입니다.