Dart: 그것이 무엇인가, Flutter 언어의 특징과 프로그래밍

저자: IT Sectr 게시일: 2026-02-10 읽는 시간: 12 분

Dart는 Google이 만든 프로그래밍 언어로, 크로스 플랫폼 프레임워크인 Flutter를 위해 특별히 만들어졌습니다. JIT 컴파일을 통한 초고속 핫 리로드와 AOT 컴파일을 통한 릴리스 빌드의 네이티브 성능을 결합합니다. Dart는 모바일 개발뿐만 아니라 웹 애플리케이션(AngularDart) 및 서버 측 솔루션에도 사용됩니다. 언어의 기능에 대한 자세한 내용은 Dart 공식 문서를 참조하세요.

핵심 요점

  • Dart — Google이 만든 Flutter 언어, JIT/AOT 컴파일 지원
  • Null safety — Dart 2.12부터 sound null safety로 null 오류 제거
  • Isolate — 공유 메모리 없는 격리된 스레드를 통한 병렬 처리
  • Flutter — Skia/Impeller를 통해 위젯을 렌더링하는 UI 프레임워크
  • Pub.dev — Dart 및 Flutter를 위한 45,000개 이상의 라이브러리를 갖춘 패키지 관리자

Dart란 무엇인가?

Dart는 C와 유사한 구문을 가진 프로그래밍 언어로, Google이 Lars Bak(Eclipse 창시자)의 주도로 개발했습니다. 첫 번째 릴리스는 2011년이었지만, Dart가 진정한 인기를 얻은 것은 2018년 Flutter 1.0 출시 이후입니다. 이 언어는 사용자 인터페이스 구축을 위해 설계되었으며, 스트림, 퓨처 및 리액티브 패턴에 대한 내장 지원을 제공합니다.

Dart의 철학은 「성능과 생산성의 균형」입니다. 이 언어는 두 가지 컴파일 전략을 지원합니다: 핫 리로드를 이용한 개발용 JIT(Just-In-Time)와 네이티브 성능의 릴리스 빌드용 AOT(Ahead-Of-Time)입니다. JIT 컴파일러는 APK 재컴파일 없이 밀리초 단위로 실행 중인 애플리케이션에 수정된 코드를 주입합니다 — 이것이 모바일 개발에서 다른 언어에 비해 Dart의 핵심 장점입니다.

Dart의 주요 기능은 Dart 2.12(2021)에 도입된 sound null safety입니다. 타입 시스템은 변수가 명시적 선언(int?) 없이는 null이 될 수 없음을 보장합니다. 이는 컴파일 타임에 NullPointerException을 제거합니다. Google에 따르면 null safety 도입으로 프로덕션 환경에서 Flutter 애플리케이션의 충돌률이 30% 감소했습니다.

Dart 생태계

Dart 생태계는 세 가지 주요 영역으로 구성됩니다: Flutter(모바일 및 데스크톱 애플리케이션), AngularDart(웹 애플리케이션), Dart Server(서버 측 솔루션). Flutter가 지배적인 플랫폼입니다: Statista(2025)에 따르면 Flutter는 크로스 플랫폼 모바일 프로젝트의 46%에서 사용되어 React Native(38%) 및 Xamarin(8%)을 앞서고 있습니다.

Dart 구문: 타입, 함수 및 클래스

Dart 구문은 Java 및 JavaScript와 유사하지만 고유한 구조를 가지고 있습니다. Dart에서는 모든 것이 객체입니다 — int, double, bool도 Object를 상속합니다. 타입 지정은 선택 사항입니다: var로 선언된 변수는 자동으로 타입을 추론하지만, 가독성과 성능을 위해 타입을 명시적으로 지정하는 것이 좋습니다.

기본 타입 및 선언

Dart는 int, double, String, bool, List, Set, Map, Record, Symbol 및 Runes를 지원합니다. Nullable 타입 — 접미사 ?가 있는 모든 타입(int?, String?). ?? 연산자(null-aware)는 왼쪽이 null인 경우 오른쪽 값을 반환합니다. 계단식 표기법(..)을 사용하면 참조를 반복하지 않고 동일한 객체에서 여러 메서드를 호출할 수 있습니다.

dart
// Dart의 기본 타입 및 선언
void main() {
  // 명시적 타입 지정
  int age = 25;
  double price = 19.99;
  String name = 'Dart';
  bool isValid = true;

  // Null safety — 변수가 null일 수 있음
  int? nullableAge = null;
  int result = nullableAge ?? 0; // null-aware 연산자

  // 제네릭을 사용한 컬렉션
  List<String> items = ['Dart', 'Flutter', 'Mobile'];
  Map<String, dynamic> config = {
    'version': '3.0',
    'mode': 'debug',
  };

  // 계단식 표기법
  final list = <String>[]
    ..add('one')
    ..add('two')
    ..sort();
}

// Record — 익명 불변 타입
(String, int) user = ('Alice', 30);
print(user.$1); // 'Alice'

dynamic 타입은 타입 검사를 비활성화합니다 — JSON 또는 동적 데이터로 작업할 때만 사용하세요. Record는 Dart 3.0의 새로운 타입으로, 별도의 클래스를 만들지 않고 값을 그룹화할 수 있습니다. Null-aware 연산자 ??는 긴 if-else 검사를 대체하여 nullable 값으로 작업하는 표준 방법입니다.

클래스와 믹스인

Dart의 클래스 — 단일 상속(extends), 믹스인(mixin)을 통한 다중 상속. Dart는 인터페이스를 별도의 개념으로 지원하지 않습니다 — 모든 클래스는 구현(implements)될 수 있습니다. 믹스인은 생성자가 없는 클래스로, with 키워드를 사용하여 모든 클래스에 메서드와 필드를 추가할 수 있습니다.

dart
// Dart의 클래스, 상속 및 믹스인
abstract class Animal {
  void sound(); // 추상 메서드
}

mixin Swimmer {
  void swim() => print('Swimming...');
}

mixin Flyer {
  void fly() => print('Flying...');
}

class Duck extends Animal with Swimmer, Flyer {
  @override
  void sound() => print('Quack!');
}

void main() {
  final duck = Duck();
  duck.sound(); // Quack!
  duck.swim();  // Swimming...
  duck.fly();   // Flying...
}

// 명명된 생성자
class Config {
  final String env;

  Config.development() : env = 'dev';
  Config.production()  : env = 'prod';
}

Duck 클래스는 Animal을 상속하고 Swimmer와 Flyer라는 두 개의 믹스인을 사용합니다. 이는 다이아몬드 문제 없이 다중 상속을 보여줍니다: 믹스인은 선형적으로 해결됩니다(super chain). 명명된 생성자(Config.development)는 미리 설정된 매개변수로 객체를 생성하기 위한 정적 팩토리 메서드의 대안입니다.

Dart의 비동기: Future, Stream 및 async/await

Dart의 비동기는 Future(단일 값), Stream(값의 시퀀스) 및 async/await를 통해 구현됩니다. Dart는 JavaScript와 유사한 이벤트 루프가 있는 단일 스레드 모델을 사용하지만, 중요한 차이점이 있습니다: Dart 코드가 Isolate(공유 메모리가 없는 별도의 스레드)에서 실행되므로 긴 계산이 UI를 차단하지 않습니다.

Future는 일정 시간 후에 완료될 비동기 작업을 나타냅니다. Future는 보류 중(대기), 값으로 완료(성공) 또는 오류로 완료(오류) 상태일 수 있습니다. .then().catchError() 체인은 async/await의 대안이지만, 가독성을 위해 await를 사용하는 것이 좋습니다.

dart
// Future와 Stream을 사용한 비동기 데이터 로딩
import 'dart:convert';
import 'package:http/http.dart' as http;

class ApiService {
  final String baseUrl;

  ApiService(this.baseUrl);

  // 단일 요청을 위한 Future
  Future<Map<String, dynamic>> fetchUser(int id) async {
    final response = await http.get(
      Uri.parse('$baseUrl/users/$id'),
    );

    if (response.statusCode == 200) {
      return jsonDecode(response.body);
    } else {
      throw Exception('Failed to load user: ${response.statusCode}');
    }
  }

  // 데이터 시퀀스를 위한 Stream
  Stream<int> countStream(int max) async* {
    for (var i = 1; i <= max; i++) {
      await Future.delayed(Duration(seconds: 1));
      yield i;
    }
  }
}

void main() async {
  final api = ApiService('https://api.example.com');

  // await 사용
  final user = await api.fetchUser(1);
  print('User: ${user['name']}');

  // await for로 Stream 처리
  await for (final count in api.countStream(5)) {
    print('Count: $count');
  }
}

ApiService 클래스는 두 가지 유형의 비동기를 보여줍니다: HTTP 요청(단일 응답)을 위한 Future와 순차 카운터(async* 및 yield를 사용한 생성기)를 위한 Stream입니다. Stream은 센서, 위치 정보, Firebase Realtime Database 등 데이터가 지속적으로 도착하는 모든 곳에서 효과적입니다. Isolate는 별도의 메모리를 사용하며 데이터는 SendPort/ReceivePort를 통해 전송됩니다.

Dart와 Flutter: 애플리케이션 아키텍처

Dart와 Flutter는 단일 스택을 형성합니다: Flutter는 UI 프레임워크, Dart는 UI 설명 언어입니다. Flutter에서는 버튼부터 전체 애플리케이션까지 모든 것이 위젯(Widget)입니다. 위젯은 stateful(변경 가능한 상태)과 stateless(변경 불가능)일 수 있습니다. Dart는 선언적 UI를 설명합니다: build()는 Flutter가 Skia(iOS에서는 Impeller)를 사용하여 렌더링하는 위젯 트리를 반환합니다.

Flutter 애플리케이션 구조

Dart의 Flutter 애플리케이션은 main() → runApp(MyApp()) → MaterialApp으로 구성됩니다. MaterialApp에는 라우팅(routes), 테마(theme) 및 지역화가 포함됩니다. 각 화면은 AppBar, Body(일반적으로 Column/ListView) 및 BottomNavigationBar를 포함하는 Scaffold입니다. Navigator.push/pop 또는 명명된 라우트를 통한 탐색.

dart
// Dart의 간단한 Flutter 애플리케이션
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Dart Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  int _counter = 0;

  void _increment() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Dart + Flutter')),
      body: Center(
        child: Text('Counter: $_counter'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _increment,
        child: Icon(Icons.add),
      ),
    );
  }
}

HomeScreen 위젯은 내부 상태 _counter를 가진 StatefulWidget입니다. setState()를 호출하면 Flutter에 UI 재구축이 알려집니다 — Dart 코드가 build()를 다시 실행하여 새 위젯 트리를 만듭니다. Flutter는 이전 트리와 새 트리를 효율적으로 비교(diff)하여 화면의 변경된 부분만 업데이트합니다. Hot Reload는 _counter 상태를 재설정하지 않고 build()를 대체합니다.

Dart 컴파일: JIT 대 AOT

Dart 컴파일은 하이브리드입니다: 개발용 JIT와 프로덕션용 AOT입니다. 디버그 모드에서 Dart VM은 코드 핫 스왑 기능으로 바이트코드를 해석하는 JIT 컴파일러를 실행합니다. 릴리스 모드에서 dart compile exe 또는 flutter build는 특정 아키텍처(arm64, x86_64, armv7)에 대한 네이티브 AOT 바이너리를 생성합니다.

모드컴파일실행 속도바이너리 크기핫 리로드
DebugJIT (VM)중간~50 MB
ReleaseAOT (네이티브)최대~15-20 MB아니오
Webdart2js브라우저에 따라 다름가변개발 서버

디버그 모드에서 Dart JIT 컴파일은 약 1초 만에 핫 리로드를 제공합니다 — 개발자는 애플리케이션 상태를 잃지 않고 UI 변경 사항을 확인합니다. AOT 컴파일은 네이티브 Swift/Kotlin 애플리케이션에 가까운 성능을 제공합니다. Google에 따르면 Dart AOT의 Flutter는 중간급 기기에서도 60 FPS 애니메이션을 달성합니다.

Dart 개발자 도구

Dart 개발자 도구에는 Dart SDK(dart 컴파일러, dartanalyzer, dartfmt, pub), Flutter SDK 및 IDE 플러그인이 포함됩니다. Dart SDK는 Flutter SDK와 함께 flutter/bin/cache/dart-sdk 폴더에 설치됩니다. Pub은 pubspec.yaml을 읽고 pub.dev에서 종속성을 다운로드하는 패키지 관리자입니다.

주요 도구

dart analyze — 타입, 사용되지 않는 가져오기 및 잠재적 오류를 확인하는 정적 분석기. dart format — 코드를 일관된 스타일로 자동으로 포맷하는 포맷터. dart doc — /// 주석에서 문서를 생성하는 생성기. Flutter DevTools — 위젯 트리 검사기, 로그, 메모리 및 네트워크가 있는 프로파일러. Dart VM Service — WebSocket을 통한 실행 중인 애플리케이션 디버깅.

yaml
# pubspec.yaml — Dart 프로젝트 구성
name: my_flutter_app
description: A new Flutter project.
version: 1.0.0

environment:
  sdk: '>=3.0.0 <4.0.0'

dependencies:
  flutter:
    sdk: flutter
  http: ^1.2.0
  provider: ^6.1.0
  shared_preferences: ^2.2.0
  json_annotation: ^4.8.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner: ^2.4.0
  json_serializable: ^6.7.0
  flutter_lints: ^3.0.0

pubspec.yaml 파일은 Dart 프로젝트 종속성을 설명합니다. environment:sdk 필드는 Dart 버전을 지정합니다 — 현재 안정 버전은 3.x입니다. Dependencies는 주요 라이브러리이고, dev_dependencies는 테스트 및 코드 생성을 위한 것입니다. json_annotation + json_serializable은 build_runner를 통해 JSON 직렬화 코드를 생성합니다. flutter_lints는 분석기를 위한 규칙 세트입니다.

자주 묻는 질문

Dart란 무엇인가?

Dart는 Google(2011)의 프로그래밍 언어로, Flutter를 사용한 크로스 플랫폼 개발을 위해 설계되었습니다. C와 유사한 구문, 강력한 타입 지정, JIT 및 AOT 컴파일을 지원합니다. sound null safety(Dart 2.12부터)와 Future 및 Stream을 통한 비동기 처리가 특징입니다. 모바일, 웹 및 데스크톱 애플리케이션에 사용됩니다.

Dart와 JavaScript의 차이점은 무엇인가?

Dart는 네이티브 코드(AOT) 또는 JS(dart2js)로 컴파일되고, JavaScript는 인터프리트됩니다. Dart는 sound null safety, 내장 클래스 및 믹스인을 갖춘 강력한 타입 지정이 있습니다. Dart의 비동기는 Isolate(공유 메모리가 없는 별도의 스레드) 기반이고, JS는 Web Workers를 사용한 이벤트 루프 기반입니다. 모바일 시나리오에서 Dart AOT 성능은 V8 JIT보다 30-50% 높습니다.

Dart는 어떻게 모바일 애플리케이션으로 컴파일되나요?

Dart는 Dart Native를 통해 AOT로 네이티브 ARM 코드로 컴파일됩니다. 디버그 모드에서 Dart VM은 핫 리로드와 함께 JIT를 사용합니다. Flutter Engine(C++)은 Skia/Impeller를 통해 UI를 렌더링합니다. Android의 경우 flutter build apk, iOS의 경우 flutter build ios입니다. 웹 빌드는 dart2js 또는 dart2wasm을 사용합니다. 릴리스 APK 크기는 15-20MB입니다(AAB 분할 제외).

Dart는 어떤 데이터 타입을 지원하나요?

Dart는 기본 타입(int, double, String, bool), 컬렉션(List, Set, Map, Record), 특수 타입(Symbol, Runes, Null)을 지원합니다. 기본 타입을 포함한 모든 것이 객체입니다. Null safety: int?는 null을 허용하고, int는 절대 null이 아닙니다. ??, ??= 연산자로 안전한 null 처리를 합니다. 제네릭: List<String>, Map<String, dynamic>.

Dart 개발에 필요한 도구는 무엇인가요?

Flutter SDK에는 Dart SDK, Flutter Engine 및 위젯 라이브러리가 포함됩니다. IDE — Flutter 플러그인이 있는 Android Studio 또는 VS Code. DevTools — 위젯 검사기가 있는 프로파일러. Pub.dev — 45,000개 이상의 라이브러리를 갖춘 패키지 관리자. dart analyze 및 dart format 도구는 코드 품질을 보장합니다. JSON 모델의 코드 생성을 위한 Build_runner.

요약

  • Dart — Flutter를 위한 Google의 언어, JIT 개발과 AOT 성능 결합
  • Sound null safety Dart 2.12(+3.0)부터 — 타입 수준에서 필수 null 보호
  • 비동기 Future(단일 결과), Stream(시퀀스), Isolate(병렬 처리)를 통해
  • Flutter — 모든 것이 위젯인 선언적 UI 프레임워크(StatelessWidget / StatefulWidget)
  • Hot Reload — 애플리케이션 상태 유지하며 약 1초 만에 JIT 코드 리로드
  • Pub.dev — pubspec.yaml을 통해 관리되는 패키지 생태계(45,000개 이상)
  • Flutter DevTools — 위젯 검사기, 메모리 및 네트워크가 있는 프로파일러

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기