🦁
Dart で条件を満たしたものだけが入る型を作る
アカウント名は前後に空白が入らずに, 1文字以上 50文字以内である必要があるとする.
そういうときに, このように条件を満たしていることを保証する型 (class) を作成することによって条件を満たしているかの確認し忘れが減る.
account_name.dart
import 'package:meta/meta.dart';
/// アカウント名. 文字数条件を満たしていることを保証される
class AccountName {
final String value;
const AccountName._(this.value);
/// `String` からアカウント名を作成する. 条件を満たしていないものは `null` が返される
static AccountName? fromString(final String raw) {
final trimmed = raw.trim();
if (trimmed.isEmpty || trimmed.length >= 50) {
return null;
}
return AccountName._(trimmed);
}
/// String` からアカウント名を作成する. 条件を満たしていないものが渡されたときにはエラーが発生する
static AccountName fromStringOrThrow(final String raw) {
final normalized = fromString(raw);
if (normalized == null) {
throw Exception("$raw is invalid account name");
}
return normalized;
}
bool operator ==(final Object other) {
return other is AccountName && value == other.value;
}
int get hashCode => value.hashCode;
String toString() {
return "AccountName($value)";
}
}
解説
const AccountName._(this.value);
の部分で, private constructor を作成しているため, 外部のファイルから AccountName
を直接作成することはできなくなっている
use.dart
import 'account_name.dart';
void main() {
final rafyaAccountName = AccountName("rafya");
}
このように使う
import 'account_name.dart';
void main() {
final rafyaAccountName = AccountName.fromString("rafya");
if (rafyaAccountName == null) {
print("不正なアカウント名です");
return;
}
print(rafyaAccountName.value); // rafya
}
Discussion