다트 3.0의 새로운 기능
다트 3.0의 새로운 기능 소개
Dart 3.0은 안정성, 생산성, 성능을 강화한 최신 버전입니다. 새로운 기능과 개선된 문법을 간단한 예제와 함께 소개합니다.
널 안전성 (Null Safety) 강화
널 안전성은 다트 언어의 핵심 철학 중 하나로, 변수나 값이 null로 인해 발생하는 런타임 에러를 방지하기 위한 개념입니다. 다트 3.0에서는 널 안전성이 더욱 강화되었으며, 모든 변수는 기본적으로 null 값을 가질 수 없습니다.
만약 null 값을 허용하려면 변수 타입 뒤에 ?를 명시해야 합니다. 이는 코드의 안정성과 신뢰성을 높이는 중요한 메커니즘입니다.
예를 들어, 널을 허용하지 않는 변수는 값이 초기화되지 않은 상태로 선언될 수 없습니다. 반대로, null 값을 허용하는 변수는 초기화되지 않은 상태에서 null을 가질 수 있습니다.
void main() {
String name = "홍길동"; // null 불가능
String? nickname; // null 가능
print(name);
print(nickname); // null 출력 가능
}레코드 (Records)
레코드는 다트 3.0에서 새롭게 추가된 데이터 구조로, 여러 값을 하나의 그룹으로 묶어 관리할 수 있는 기능입니다. 레코드는 간단한 데이터를 함께 저장하고 관리하기 위한 용도로 설계되었으며, 튜플과 유사합니다.
레코드는 두 가지 방식으로 선언할 수 있습니다:
- 포지셔널 파라미터: 값을 위치 기반으로 저장하며, 순서를 엄격히 지켜야 합니다.
- 네임드 파라미터: 값에 이름을 부여해 저장하며, 순서와 상관없이 접근할 수 있습니다.
레코드는 데이터의 직관적인 표현과 코드의 간결성을 제공합니다.
void main() {
var record = ('홍길동', 25, '서울'); // 레코드 생성
print(record.$1); // 홍길동
print(record.$2); // 25
print(record.$3); // 서울
var namedRecord = (name: '홍길동', age: 25);
print(namedRecord.name); // 홍길동
print(namedRecord.age); // 25
}패턴 매칭 (Pattern Matching)
패턴 매칭은 다트 3.0에서 추가된 강력한 기능으로, 값의 구조를 분석하여 원하는 데이터를 추출하거나 조건에 따라 다른 작업을 수행할 수 있습니다.
이는 리스트, 맵, 레코드, 그리고 기타 복합 데이터 구조를 처리하는 데 매우 유용합니다.
패턴 매칭은 switch 문과 함께 사용할 때 특히 강력하며, 값을 분류하거나 특정 조건에 따라 다른 작업을 수행할 수 있도록 지원합니다.
예를 들어, 리스트의 특정 구조를 확인하거나 데이터 그룹에서 일부 값을 추출하는 데 사용됩니다.
리스트 패턴 매칭
void main() {
var numbers = [1, 2, 3];
switch (numbers) {
case [1, 2, 3]:
print("리스트가 1, 2, 3 입니다.");
case [1, 2]:
print("리스트가 1, 2 입니다.");
default:
print("다른 리스트입니다.");
}
}데이터 추출
void main() {
var record = (name: '홍길동', age: 25);
if (record case (name: var name, age: int age)) {
print('이름: $name, 나이: $age');
}
}클래스 변경자 (Class Modifiers)
클래스 변경자는 클래스의 동작과 사용을 제한하거나 특정 규칙을 강제하는 데 사용됩니다. 다트 3.0에서는 다음과 같은 클래스 변경자가 도입되었습니다:
- sealed: 클래스가 외부에서 상속되거나 재정의되지 않도록 제한합니다.
- base: 상속만 가능하도록 설정하며, 외부 구현은 허용되지 않습니다.
- final: 상속 및 재정의가 불가능한 불변 클래스입니다.
- interface: 외부 파일에서 상속하지 못하도록 제한하며, 오직 인터페이스로 사용됩니다.
이러한 변경자는 코드의 유지보수성과 안정성을 높이는 데 기여합니다.
sealed 클래스
sealed class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
void main() {
Animal animal = Dog();
switch (animal) {
case Dog():
print("강아지입니다.");
case Cat():
print("고양이입니다.");
}
}base 클래스
base class Vehicle {}
class Car extends Vehicle {}
class Bike extends Vehicle {} // base 클래스 상속 가능final 클래스
final class Immutable {}
// final 클래스는 상속 불가능
class NewClass extends Immutable {} // 에러 발생interface 클래스
interface class Payment {
void processPayment();
}
class CreditCardPayment implements Payment {
@override
void processPayment() {
print("신용카드 결제 처리 중...");
}
}
void main() {
Payment payment = CreditCardPayment();
payment.processPayment();
}강화된 switch 문 (Enhanced Switch Statements)
다트 3.0에서는 switch 문이 크게 개선되어, 표현식을 반환하거나 조건부 값을 처리할 수 있습니다.
이제 switch 문을 단순히 조건 분기 도구로 사용하는 것뿐만 아니라, 직접 값을 반환하거나 변수에 할당하는 기능을 사용할 수 있습니다.
이러한 기능은 코드의 간결성을 높이고, 조건 처리 로직을 명확하게 표현할 수 있도록 도와줍니다.
void main() {
int number = 3;
var result = switch (number) {
1 => "하나",
2 => "둘",
3 => "셋",
_ => "기타"
};
print(result); // 셋
}정적 메타 프로그래밍 (Static Meta-programming)
정적 메타 프로그래밍은 다트 3.0에서 도입된 중요한 기능 중 하나로, 코드 생성과 타입 안정성을 개선하는 데 사용됩니다.
정적 메타 프로그래밍을 사용하면 런타임에서 발생할 수 있는 오류를 컴파일 단계에서 방지할 수 있으며, 복잡한 작업을 더 효율적으로 처리할 수 있습니다.
이는 대규모 프로젝트나 복잡한 로직을 처리할 때 코드의 재사용성과 가독성을 크게 향상시킵니다.
class Calculator {
static int add(int a, int b) => a + b;
}
void main() {
print(Calculator.add(3, 5)); // 8
}새로운 내장 함수 (New Built-in Functions)
다트 3.0에서는 개발자 경험을 개선하기 위해 새로운 내장 함수들이 추가되었습니다.
예를 들어, mapEntries와 같은 새로운 메서드는 맵 데이터를 더욱 직관적이고 효율적으로 처리할 수 있도록 도와줍니다.
이 외에도 여러 유용한 함수들이 추가되어 코드의 간결성과 기능성을 강화합니다.
void main() {
var map = {'a': 1, 'b': 2};
map.mapEntries.forEach((entry) {
print('${entry.key}: ${entry.value}');
});
}강화된 열거형 (Enhanced Enum)
열거형은 다트 3.0에서 크게 확장되어 값과 메서드를 가질 수 있게 되었습니다.
열거형은 데이터의 상태를 표현하는 데 사용되며, 기존의 단순한 상태 표시를 넘어 복잡한 로직을 구현할 수 있도록 개선되었습니다.
이제 열거형은 각각의 값을 메서드로 정의하여, 특정 상태와 연관된 동작을 직접 실행할 수 있습니다.
이는 상태 기반 프로그래밍을 보다 명확하고 직관적으로 구현할 수 있도록 도와줍니다.
enum Weather {
sunny("맑음"),
cloudy("흐림"),
rainy("비");
final String description;
const Weather(this.description);
void display() {
print(description);
}
}
void main() {
Weather.sunny.display(); // 맑음
}