はじめに
dart上でのEnum/String 変換に関する記事をよく見かけるのですが、内容が古いものが多い印象があったので2022年9月最新版ということで記事にしておきます。
Enum → Stringの変換
Dart2.17以降ではこのように実装できます。
void main() {
var name = Align.left.displayName;
print(name); // 「左」
}
enum Align{
left('左'), // Enumのメンバ宣言部分でフィールドも定義できる!
center('中央'),
right('右'),
;
const Align(this.displayName);
// フィールド生やし放題
final String displayName;
}
2.17より古いバージョンだともう少しガチャガチャする必要がありこんなかんじ。
void main() {
var name = Align.left.name;
print(name); // 「左」
}
enum Align{
left,
center,
right,
}
extension AlignExtensions on Align{
String get name {
switch(this){
case Align.left:
return '左';
case Align.center:
return '中央';
case Align.right:
return '右';
}
}
}
ちなみに
単にenum定義の文字列が必要なだけの場合、dart 2.15以降では「name」プロパティが利用できます。
void main() {
var name = Align.left.name;
print(name); // 「left」
}
String→Enumの変換
2.17以降のバージョンではSDK純正のメソッドが用意されていますのでこちらを使いましょう。
var left = Align.values.byName('left');
昔はこんな感じにこねくりまわす必要があったみたいです。便利な世の中になりました。
ちなみに
byNameメソッドは大文字小文字を区別しています。諸事情によりdartの定義と判定文字列の大文字小文字が異なる場合は自分で拡張メソッドをはやしてあげる必要がありそうでした。
void main() {
var leftNG = Align.values.byName('LEFT');
// ⇒ Uncaught Error: Invalid argument (name): No enum value with that name: "LEFT"
var leftOK = Align.values.byNameIgnoreCase('LEFT');
// OK
}
extension EnumByNameIgnoreCase<T extends Enum> on Iterable<T> {
T byNameIgnoreCase(String name) {
for (var value in this) {
if (value.name.toLowerCase() == name.toLowerCase()) return value;
}
throw ArgumentError.value(name, "name", "No enum value with that name");
}
}
ちなみに(その2
どうしても2.17を使えない場合...2.14以上であればenumがEnum抽象クラスを継承するようになっているので自力での実装も可能のようです