# Dart의 주요 특징

#### 1. 단일 언어로 웹과 모바일을 아우름

Dart는 단일 언어로 웹과 모바일 애플리케이션 모두를 개발할 수 있는 특징을 가지고 있다. Dart는 Flutter 프레임워크와 함께 사용되어 모바일 애플리케이션을 개발하는 데 많이 활용된다. 또한, Dart는 **웹 애플리케이션** 개발에도 적합하며, 이는 **Dart to JavaScript** 컴파일러를 통해 가능한다. Dart로 작성된 코드는 JavaScript로 변환되어 웹 브라우저에서도 문제없이 실행된다.

이처럼 Dart는 **단일 언어**로 다양한 플랫폼을 지원함으로써 코드 재사용성을 높이고 개발 속도를 크게 향상시킬 수 있다.

#### 2. 성능 최적화된 언어

Dart는 성능 최적화를 위해 두 가지 실행 방식을 지원한다:

* **Ahead-of-Time (AOT) 컴파일**: Dart는 모바일 애플리케이션 개발에서 AOT 컴파일을 통해 성능을 최적화한다. 코드를 미리 컴파일하여 기계어로 변환함으로써 애플리케이션 실행 속도를 크게 높일 수 있다.
* **Just-in-Time (JIT) 컴파일**: JIT 컴파일은 주로 개발 중 코드의 실시간 변화를 빠르게 반영할 수 있도록 도와준다. 코드가 실행되는 동안에 컴파일이 이루어져 즉시 반영되는 장점이 있다.

AOT와 JIT 컴파일 방식을 모두 지원함으로써 Dart는 **개발 중의 생산성**과 **배포 시 성능**을 동시에 만족시킬 수 있다.

#### 3. 간결하고 직관적인 문법

Dart는 문법이 간결하고 직관적이어서 초보자도 쉽게 접근할 수 있는 언어이다. 특히 **변수 타입 추론** 기능이 있어 개발자가 명시적으로 타입을 지정하지 않더라도, Dart 컴파일러가 자동으로 변수의 타입을 추론한다.

```dart
var name = 'Hello Dart';  // String 타입으로 추론됨
int number = 42;      	  // 명시적으로 타입을 지정
```

위 예제에서 보듯이, `var` 키워드를 사용하여 타입을 생략할 수 있고, 필요 시 타입을 명시적으로 지정할 수도 있다.

#### 4. 강력한 비동기 프로그래밍 지원

Dart는 비동기 프로그래밍을 매우 쉽게 지원한다. **async**와 **await** 키워드를 통해 비동기 작업을 처리할 수 있으며, 이는 코드의 가독성을 높이는 데 큰 기여를 한다. Dart의 **Future**와 **Stream**은 비동기 작업을 처리하는 두 가지 주요 방식이다.

**Future**

**Future**는 단일 비동기 작업을 처리하는 객체이다. 예를 들어, 네트워크 요청이나 파일 I/O와 같은 시간이 걸리는 작업을 비동기적으로 수행하고, 그 결과를 나중에 받을 수 있다.

```dart
Future<String> fetchData() async {
  return 'Data fetched';
}

void main() async {
  print(await fetchData());
}
```

위 코드에서 `fetchData` 함수는 비동기 작업을 나타내며, **await** 키워드를 사용하여 작업이 완료될 때까지 기다렸다가 결과를 출력한다.

**Stream**

**Stream**은 데이터의 **연속적인 흐름**을 처리할 때 사용된다. 이는 여러 개의 비동기 데이터를 처리하거나 이벤트 기반의 데이터를 처리할 때 유용하다. 예를 들어, 실시간으로 데이터가 들어오는 상황을 처리할 때 Stream을 사용한다.

```dart
Stream<int> numberStream() async* {
  for (int i = 1; i <= 3; i++) {
    yield i;
  }
}

void main() async {
  await for (var number in numberStream()) {
    print(number);
  }
}
```

이 코드는 **Stream**을 통해 1부터 3까지의 숫자를 비동기적으로 전달받고, 각 숫자를 출력한다. Stream을 사용할 때 **await for** 구문을 통해 데이터 흐름을 기다리며 처리할 수 있다.

#### 5. 풍부한 표준 라이브러리

Dart는 개발자에게 매우 **풍부한 표준 라이브러리**를 제공한다. Dart의 표준 라이브러리는 기본적인 데이터 구조와 파일 I/O, HTTP 요청, JSON 처리 등 다양한 기능을 지원한다. 이러한 라이브러리 덕분에 외부 패키지를 사용하지 않고도 많은 기능을 구현할 수 있다.

예를 들어, **JSON 데이터 처리**는 Dart에서 매우 간단하게 이루어진다.

```dart
import 'dart:convert';

void main() {
  String jsonData = '{"name": "ChatGPT", "version": "4.0"}';
  Map<String, dynamic> parsedData = jsonDecode(jsonData);
  print(parsedData['name']);
}
```

위 코드에서는 **dart:convert** 라이브러리를 통해 JSON 데이터를 파싱하고, 그 결과를 **Map** 형태로 변환한 후 값을 출력한다. 이처럼 Dart는 표준 라이브러리만으로도 많은 작업을 손쉽게 처리할 수 있다.

#### 6. 안정성과 보안성을 고려한 설계

Dart는 **안정성**과 **보안성**을 매우 중요시하여 설계되었다. Dart의 **타입 시스템**은 **정적 타입**을 기반으로 하며, 컴파일 시점에 타입 검사를 수행하여 많은 오류를 미리 방지할 수 있다. 또한, **null safety** 기능을 통해 **null 참조 오류**를 방지할 수 있다.

Dart의 null safety는 코드에서 null 값을 허용하지 않는 변수를 엄격히 관리하며, null 값이 될 수 있는 변수를 명시적으로 정의하도록 요구한다.

```dart
String? nullableString = null; // null을 허용하는 변수
String nonNullableString = 'Hello'; // null을 허용하지 않는 변수
```

이러한 강력한 타입 시스템과 null safety는 코드의 안정성을 높이고, 런타임 오류를 최소화하는 데 기여한다.

#### 7. 빠른 개발 주기

Dart는 **빠른 개발 주기**를 지원하는 언어이다. 특히, Flutter와 함께 사용할 경우 **Hot Reload** 기능을 통해 개발자가 코드를 수정하고 즉시 변경 사항을 애플리케이션에서 확인할 수 있다. 이는 개발 속도를 크게 향상시키며, 실시간으로 UI를 조정하거나 논리적 변경 사항을 테스트할 수 있게 해준다.

* **Hot Reload**: 코드 수정 후 애플리케이션을 다시 실행하지 않고도 변경 사항을 즉시 적용할 수 있다. 이는 개발자에게 매우 편리한 기능으로, UI나 비즈니스 로직을 신속하게 테스트하고 수정하는 데 유용하다.
* **Hot Restart**: 애플리케이션의 상태를 초기화하여 처음부터 다시 시작하는 방식이다. 더 큰 변경 사항을 테스트할 때 유용하며, 기존 상태에 영향을 주지 않으면서 앱을 초기 상태로 재실행할 수 있다.

#### 8. Dart의 안정적인 컴파일러

Dart는 다양한 환경에서 효율적으로 실행될 수 있도록 설계된 컴파일러를 제공한다. Dart의 컴파일러는 JavaScript로의 컴파일뿐만 아니라, 네이티브 코드로의 컴파일도 지원한다. Dart는 **Dart VM**과 **Dart Native** 두 가지 주요 컴파일 방식을 통해 다양한 플랫폼에 최적화된 실행 환경을 제공한다.

* **Dart VM**: 개발 중 빠른 테스트와 디버깅을 위해 사용되며, JIT 컴파일 방식을 통해 빠른 코드 변화를 반영할 수 있다.
* **Dart Native**: 모바일 및 데스크탑 애플리케이션을 위한 AOT 컴파일을 지원하며, 최적화된 기계어 코드를 생성해 높은 성능을 보장한다.
* **Dart2js**: Dart 코드를 JavaScript 코드로 변환하여 브라우저 환경에서 실행할 수 있도록 도와준다. 이를 통해 웹 애플리케이션도 Dart로 개발할 수 있다.

#### 9. 확장성 있는 아키텍처 지원

Dart는 대규모 프로젝트에서의 확장성을 고려하여 설계되었다. Dart의 모듈화 및 패키지 관리 시스템은 프로젝트를 여러 모듈로 나누어 개발할 수 있도록 하며, **pub.dev**에서 다양한 패키지를 쉽게 찾아 설치할 수 있다. 이는 개발자가 필요에 맞는 외부 라이브러리를 손쉽게 통합하여 개발 효율성을 높일 수 있게 해준다.

**패키지 관리 시스템**

Dart는 **pub.dev**라는 중앙 저장소를 통해 수많은 오픈소스 패키지를 제공하며, 이는 개발자의 작업을 크게 단축시켜 준다. 개발자는 `pubspec.yaml` 파일을 사용하여 프로젝트에서 사용할 패키지를 정의하고, **pub** 툴을 사용해 패키지를 설치 및 관리할 수 있다.

```yaml
name: my_project
dependencies:
  http: ^0.13.3
  path: ^1.8.0
```

위 예제는 `pubspec.yaml` 파일에 두 가지 패키지 의존성을 추가한 예이다. Dart는 이러한 패키지 관리 시스템을 통해 확장성과 모듈화를 손쉽게 지원한다.
