패턴과 레코드:
레코드는 다양한 시나리오에서 사용할 수 있으며, 데이터를 표현하는 데 레코드 유형을 사용할 수 있습니다. 이를 통해 여러 반환 값이 있는 함수를 생성할 수 있습니다. 레코드는 클래스의 가벼운 대안으로 볼 수 있으며, 'Map'이나 'List'보다 타입 안정성이 높습니다. 레코드는 명명된 인수와 위치 인수(또는 둘 다)를 지원하며, 디스트럭처링을 사용하여 코드를 더욱 간소화할 수 있습니다.
(String, int, int) getPerson(Map<String, dynamic> json) {
return (
json['name'],
json['age'],
json['height'],
);
}
final person = getPerson(json);
print(person.$1); // 'Andrea'
print(person.$2); // 38
print(person.$3); // 184
또한, 레코드는 디스트럭처링을 지원합니다. 디스트럭처링을 사용하여 반환된 값을 이렇게 분해할 수 있습니다:
final (name, age, height) = getPerson(json);
print(name); // 'Andrea'
print(age); // 38
print(height); // 184
향상된 switch와 if-case 문장
Dart 3는 switch 표현식을 도입하였습니다. 예를 들어, 이전에 switch문을 사용하여 작성했던 코드는 다음과 같이 간결하게 재작성할 수 있습니다:
enum Move {
up,
down,
left,
right;
Offset get offset => switch (this) {
up => const Offset(0.0, 1.0),
down => const Offset(0.0, -1.0),
left => const Offset(-1.0, 0.0),
right => const Offset(1.0, 0.0),
};
}
Sealed classes 및 기타 클래스 수정자
Sealed classes는 모든 가능한 경우를 처리할 수 있도록 도와줍니다. 예를 들어, 백엔드에서 반환될 수 있는 모든 인증 예외를 정의하기 위해 Sealed classe를 사용할 수 있습니다:
sealed class AuthException implements Exception {}
class EmailAlreadyInUseException extends AuthException {
EmailAlreadyInUseException(this.email);
final String email;
}
class WeakPasswordException extends AuthException {}
class WrongPasswordException extends AuthException {}
class UserNotFoundException extends AuthException {}
String describe(AuthException exception) {
return switch (exception) {
EmailAlreadyInUseException(email: final email) =>
'Email already in use: $email',
WeakPasswordException() => 'Password is too weak',
WrongPasswordException() => 'Wrong password',
UserNotFoundException() => 'User not found',
};
}
클래스 키워드
fianl로 클래스 선언:
extends, implement, 또는 mixin으로 사용이 불가능합니다.
but 같은 파일에서는 가능합니다.
final class Person{
final String name;
final int age;
Person({
required this.name,
required this.age,
});
}
base로 클래스 선언:
base로 선언하면 extends는 가능하지만 implement는 불가능합니다.
base, sealed, final로 선언된 클래스만 extend가 가능합니다.
base class Person{
final String name;
final int age;
Person({
required this.name,
required this.age,
});
}
interface로 선언하면 implement만 가능하다.
interface class Person{
final String name;
final int age;
Person({
required this.name,
required this.age,
});
}
Sealed class 는 abstract이면서 final이다.
패턴매칭을 사용할 수 있도록 해준다.
sealed class Person{};
class Idol extends Person{};
class Engineer extends Person{};
class Chef extends Person {} //아래 스위치 문에서 에러 발생
String whoIsHe(Person person) => switch(person){
Idol i => '아이돌',
Engineer e => '엔지니어',
_ => '나머지' // 이런식으로 패턴을 매칭 시켜줘야된다.
};
mixin class
1) mixin은 extends나 with을 사용 할 수 없다. 그렇기 떄문에 mixin class 도 마찬가지로 사용불가능하다
2) 클래스는 on 키워드를 사용 할 수 없다. 그렇기 때문에 mixin class도 on 키워드를 사용 할 수 없다.
mixin class AnimalMixin{
String bark(){
return '멍멍';
}
};