다트 개요

다트 개요

다트(Dart)에 대한 짧은 소개예요.

출처: Dart overview

본문

다트는 어떤 플랫폼에서든 빠른 앱을 개발하기 위한 **클라이언트 최적화 언어(client-optimized language)**예요. 다트의 목표는 멀티 플랫폼 개발에 가장 생산적인 프로그래밍 언어를 제공하고, 앱 프레임워크를 위한 유연한 실행 런타임 플랫폼을 갖추는 거예요.

언어는 그 기술적 범위(technical envelope)—개발 과정에서 내리는 선택들, 즉 언어의 능력과 강점을 형성하는 선택들—에 의해 정의돼요. 다트는 특히 클라이언트 개발에 잘 맞는 기술적 범위를 위해 설계됐어요. 개발(1초 미만의 상태 기반 핫 리로드)과, 다양한 컴파일 대상(웹, 모바일, 데스크톱)에서의 고품질 프로덕션 경험을 모두 우선시하는 거죠.

다트는 또한 플러터(Flutter)의 기반이 돼요. 다트는 플러터 앱을 구동하는 언어와 런타임을 제공하지만, 코드 포매팅, 분석, 테스트 같은 많은 핵심 개발자 작업도 지원해요.

💡 프로그래밍이 처음이신가요? 이 페이지의 일부 개념은 고급일 수 있어요. 기초적인 입문부터 시작해 보는 걸 고려해 보세요.

다트: 언어

다트 언어는 **타입 안전(type safe)**해요. 변수의 값이 항상 그 변수의 정적 타입과 일치하도록 정적 타입 검사를 사용하죠. 이를 가리켜 사운드 타이핑(sound typing)이라고도 불러요. 타입은 필수지만, 타입 추론(type inference) 덕분에 타입 애너테이션은 선택이에요. 다트 타이핑 시스템은 유연해서, 실험 중이거나 특히 동적으로 동작해야 하는 코드에 유용하게 쓰이는 **동적 타입(dynamic)**을 런타임 검사와 결합해 사용할 수도 있어요.

다트는 내장된 **사운드 널 세이프티(sound null safety)**를 갖춰요. 이는 여러분이 허용하지 않는 한 값이 널이 될 수 없다는 뜻이에요. 사운드 널 세이프티 덕분에 다트는 정적 코드 분석을 통해 런타임 널 예외로부터 여러분을 보호해 줘요. 많은 널 세이프 언어와 달리, 다트가 어떤 변수가 널이 될 수 없다고 판단하면 그 변수는 절대 널이 될 수 없어요. 디버거에서 실행 중인 코드를 들여다보면 널이 아님이 런타임까지 유지되는 걸 볼 수 있어요. 그래서 '사운드(sound)' 널 세이프티인 거예요.

다음 코드 예시는 라이브러리, 비동기 호출, 널 가능/불가 타입, 화살표 문법, 제너레이터, 스트림, 게터 등 여러 다트 언어 기능을 보여 줘요. 언어에 대해 더 배우려면 다트 언어 투어를 확인해 보세요.

import 'dart:math' show Random;

void main() async {
  print('Compute π using the Monte Carlo method.');
  await for (final estimate in computePi().take(100)) {
    print('π ≅ $estimate');
  }
}

/// Generates a stream of increasingly accurate estimates of π.
Stream<double> computePi({int batch = 100000}) async* {
  var total = 0; // Inferred to be of type int
  var count = 0;
  while (true) {
    final points = generateRandom().take(batch);
    final inside = points.where((p) => p.isInsideUnitCircle);

    total += batch;
    count += inside.length;
    final ratio = count / total;

    // Area of a circle is A = π⋅r², therefore π = A/r².
    // We consider only non-negative x and y (that is, the
    // first quadrant), which doesn't change the ratio.
    // So, when given random points with x ∈ [0, 1],
    // y ∈ [0, 1], the ratio of those inside the unit circle
    // should approach π / 4. Therefore, the value of π
    // should be:
    yield ratio * 4;
  }
}

Iterable<Point> generateRandom([int? seed]) sync* {
  final random = Random(seed);
  while (true) {
    yield Point(random.nextDouble(), random.nextDouble());
  }
}

class Point {
  final double x;
  final double y;

  const Point(this.x, this.y);

  bool get isInsideUnitCircle => x * x + y * y <= 1;
}

이 예시는 임베디드 DartPad에서 실행되고 있어요. 이 예시를 별도 창에서 열 수도 있어요.

다트: 라이브러리

다트는 일상적인 프로그래밍 작업의 필수 요소를 제공하는 풍부한 **핵심 라이브러리(core libraries)**를 갖추고 있어요.

  • 모든 다트 프로그램을 위한 내장 타입, 컬렉션, 그리고 기타 핵심 기능 (dart:core)
  • 큐, 연결 리스트, 해시맵, 이진 트리 같은 더 풍부한 컬렉션 타입 (dart:collection)
  • JSON과 UTF-8을 포함해 서로 다른 데이터 표현 사이를 변환하는 인코더·디코더 (dart:convert)
  • 수학 상수와 함수, 그리고 난수 생성 (dart:math)
  • FutureStream 같은 클래스로 비동기 프로그래밍 지원 (dart:async)
  • 고정 크기 데이터(예: 부호 없는 8바이트 정수)와 SIMD 숫자 타입을 효율적으로 다루는 리스트 (dart:typed_data)
  • 웹이 아닌 애플리케이션을 위한 파일, 소켓, HTTP 및 기타 I/O 지원 (dart:io)
  • C 스타일 인터페이스를 제공하는 다른 코드와의 상호 운용을 위한 외부 함수 인터페이스 (dart:ffi)
  • 격리(isolate)를 통한 동시 프로그래밍—스레드와 비슷하지만 메모리를 공유하지 않고 메시지를 통해서만 통신하는 독립적인 작업자 (dart:isolate)
  • 브라우저와 Document Object Model(DOM)과 상호작용해야 하는 웹 기반 앱을 위한 HTML 요소와 기타 리소스 (dart:js_interoppackage:web)

핵심 라이브러리 너머로, 많은 API가 포괄적인 패키지 집합을 통해 제공돼요. 다트 팀은 다음과 같은 많은 유용한 보조 패키지를 배포해요.

  • characters
  • intl
  • http
  • crypto
  • markdown

추가로, 서드파티 게시자와 더 넓은 커뮤니티가 다음과 같은 기능을 지원하는 수천 개의 패키지를 배포해요.

  • XML
  • Windows 통합
  • SQLite
  • 압축(compression)

다트 핵심 라이브러리를 갖춘 일련의 작동 예시를 보려면 핵심 라이브러리 문서를 읽어 보세요. 추가 API를 찾으려면 흔히 쓰는 패키지 페이지를 확인해 보세요.

다트: 플랫폼

다트의 컴파일러 기술 덕분에 코드를 다양한 방식으로 실행할 수 있어요.

  • 네이티브 플랫폼(Native platform): 모바일과 데스크톱 기기를 대상으로 하는 앱을 위해, 다트는 JIT(just-in-time) 컴파일을 제공하는 다트 VM과 기계어를 만들어 내는 AOT(ahead-of-time) 컴파일러를 모두 포함해요.
  • 웹 플랫폼(Web platform): 웹을 대상으로 하는 앱을 위해, 다트는 개발용 또는 프로덕션용으로 컴파일할 수 있어요. 다트의 웹 컴파일러는 다트를 JavaScript 또는 WebAssembly로 변환해요.

플러터 프레임워크는 다트 플랫폼으로 구동되는 인기 있는 멀티 플랫폼 UI 툴킷이에요. iOS, Android, macOS, Windows, Linux, 웹에서 실행되는 UI 경험을 만들기 위한 도구와 UI 라이브러리를 제공해 준답니다.

다트 네이티브(기계어 JIT와 AOT)

개발 중에는 빠른 개발 사이클이 반복 작업에 중요해요. 다트 VM은 증분 재컴파일(핫 리로드를 가능하게 함), 라이브 메트릭 수집(DevTools 구동), 그리고 풍부한 디버깅 지원을 갖춘 JIT 컴파일러(just-in-time compiler)를 제공해요.

앱을 프로덕션에 배포할 준비가 되면—앱 스토어에 게시하든 프로덕션 백엔드에 배포하든—다트 AOT 컴파일러가 네이티브 ARM 또는 x64 기계어로 컴파일할 수 있어요. AOT로 컴파일된 앱은 일관되고 짧은 시작 시간으로 실행돼요.

AOT 컴파일된 코드는 사운드 다트 타입 시스템을 강제하고, 빠른 객체 할당과 세대별 가비지 컬렉터로 메모리를 관리하는 효율적인 다트 런타임 안에서 실행돼요.

다트 웹(JavaScript 개발·프로덕션과 WebAssembly)

다트 웹(Dart Web)은 JavaScript로 구동되는 웹 플랫폼에서 다트 코드를 실행할 수 있게 해 줘요. 다트 웹에서 다트 코드를 JavaScript 코드로 컴파일하면, 그 JavaScript가 브라우저에서 실행돼요—예를 들어 Chrome 안의 V8에서 말이죠. 또는 다트 코드를 WebAssembly로 컴파일할 수도 있어요.

다트 웹에는 세 가지 컴파일 모드가 있어요.

  • 증분 재컴파일(핫 리로드 가능)로 빠른 개발 사이클을 가능하게 하는 증분 JavaScript 개발 컴파일러
  • 데드 코드 제거 같은 기법을 통해 빠르고 컴팩트하며 배포 가능한 JavaScript로 다트 코드를 컴파일하는 최적화된 JavaScript 프로덕션 컴파일러
  • 다트 코드를 초고속이고 배포 가능한 WebAssembly GC 코드로 컴파일하는 최적화된 WebAssembly(WasmGC) 프로덕션 컴파일러

추가 정보:

다트 런타임

어떤 플랫폼을 쓰든, 어떻게 코드를 컴파일하든, 코드를 실행하려면 다트 런타임이 필요해요. 이 런타임은 다음의 중요한 작업들을 책임져요.

  • 메모리 관리: 다트는 관리형(managed) 메모리 모델을 사용해서, 사용하지 않는 메모리를 가비지 컬렉터(GC)가 회수해요.
  • 다트 타입 시스템 강제: 다트의 대부분 타입 검사는 정적(컴파일 시점)이지만, 일부는 동적(런타임)이에요. 예를 들어 다트 런타임은 타입 검사와 캐스트 연산자를 통해 동적 검사를 강제해요.
  • 격리 관리: 다트 런타임은 메인 격리(코드가 보통 실행되는 곳)와 앱이 만드는 다른 모든 격리를 제어해요.

네이티브 플랫폼에서 다트 런타임은 자체 포함(self-contained) 실행 파일 안에 자동으로 포함되고, dart run 명령이 제공하는 다트 VM의 일부이기도 해요.

다트 배우기

다트를 배우는 방법은 여러 가지가 있어요. 추천하는 방법 몇 가지를 소개할게요.

  • 브라우저에서 다트를 탐구해 보세요—다트 코드를 위한 웹 기반 실행 환경인 DartPad를 통해서요.
  • 명령줄용 다트 빌드의 기초를 다루는 다트 튜토리얼을 완료해 보세요.
  • 각 주요 다트 기능을 어떻게 쓰는지 보여 주는 다트 언어 투어를 둘러보세요.
  • 다트 전문가들의 방대한 온라인 교육을 수강해 보세요.
  • 다트 핵심 라이브러리를 설명하는 API 문서를 탐구해 보세요.
  • 다트 프로그래밍에 관한 을 읽어 보세요.

더 알아보기