sayu.day

Dart 핵심 문법과 실무 패턴

Dart는 AOT/JIT를 함께 지원해 개발 중에는 hot reload로 빠르게 반복하고, 배포 시에는 네이티브에 가까운 실행 성능을 냅니다. Null safety가 기본으로 적용되어 있고 Flutter와의 결합도가 높아, UI 상태를 모델링하는 데 필요한 문법(immutable, extension, async)이 풍부합니다. 이 글은 null safety부터 함수, 컬렉션, 불변 모델, 비동기까지 실무에서 자주 쓰는 순서로 핵심 문법을 정리합니다.

핵심 특징

  • AOT/JIT 동시 지원: 개발 중에는 hot reload, 배포 시에는 빠른 실행 성능
  • Null safety 기본 적용: nullable/nonnull 타입이 컴파일 단계에서 구분됨
  • Flutter와의 높은 결합: UI 상태 모델링에 필요한 문법(immutable, extension, async)이 풍부함

1) 변수와 Null Safety

void main() {
  String name = "sayu";     // non-null
  String? nickname = null;   // nullable

  if (nickname != null) {
    print(nickname.toUpperCase());
  }

  print(nickname?.toUpperCase() ?? "NO_NICKNAME");
}
  • String에는 null을 넣을 수 없습니다.
  • String?는 null이 가능하며, 사용 시 ?., ??, null check가 필요합니다.

2) 함수 시그니처

Named Parameter + Required

String formatUser({
  required String id,
  required int age,
  String country = "KR",
}) {
  return "$id:$age:$country";
}

Optional Positional Parameter

String greet(String name, [String suffix = "!"]) {
  return "Hello $name$suffix";
}

Arrow Function

int add(int a, int b) => a + b;

3) 컬렉션

void main() {
  final numbers = <int>[1, 2, 3];
  final profile = <String, Object>{
    "name": "sayu",
    "active": true,
  };
  final tags = <String>{"dart", "flutter"};

  final withCondition = [
    "base",
    if (numbers.isNotEmpty) "hasNumbers",
    for (final n in numbers) "n=$n",
  ];

  print(profile);
  print(tags);
  print(withCondition);
}

4) 클래스와 불변 모델

class User {
  final String id;
  final int age;

  const User({required this.id, required this.age});

  User copyWith({String? id, int? age}) {
    return User(
      id: id ?? this.id,
      age: age ?? this.age,
    );
  }
}

실무에서는 final 필드와 copyWith 조합이 상태 업데이트에 가장 안정적입니다.

5) 비동기

Future<String> fetchUser() async {
  await Future.delayed(const Duration(milliseconds: 100));
  return "user-1";
}

Future<void> main() async {
  final user = await fetchUser();
  print(user);
}
  • Future<T>: 단일 비동기 결과
  • Stream<T>: 연속 이벤트 처리

자주 나는 실수

  • nullable 타입을 null check 없이 접근하는 경우
  • dynamic 남용으로 컴파일 안전성을 잃는 경우
  • const/final 구분 없이 모두 가변으로 두는 설계

정리

Dart는 null safety와 명확한 타입 시스템 덕분에 대규모 코드베이스에서도 유지보수성이 좋습니다. 실무 기준으로는 required named parameter, immutable 모델, async/await 규칙화부터 먼저 잡는 것이 효과적입니다.