Dartのジェネリクスについて
概要
ジェネリクスとは、型をコンパイル時に決定する書き方である。
<>の中に型を入れる。
以下にコード例を示す。
void sample<T>(T argment){
T result = argment;
return result;
}
R sample<T,R>(T argment){
R result = argment as R;
return result;
}Dartでは、関数の横に<T>と記述するとジェネリクスとなる。
この場合、Tという型が認識される。
返り値や引き数にこのジェネリクスを定義することが出来る。
Tip
T以外にも使用者が文字を決めることが出来る。
SやR、TYPEなどでもよい。
このTは関数呼び出し時に決定することが出来る。
以下にコード例を示す。
final intValue = sample<Int>(12); //sample関数のTはInt型と認識される
final strValue = sample<String>("Hello World"); //sample関数のTはString型と認識される
void sample<T>(T argment){
T result = argment;
return result;
}このTはextendsを使用することで型を制限できる。
final intValue = sample<Int>(12);
final strValue = sample<String>("Hello World"); //エラー
void sample<T extends Int>(T argment){
T result = argment;
return result;
}クラス
クラスにも使用することが出来る。
クラスに使用するとメソッド複数で設定したジェネリクスを使用することが出来る。
以下にコード例を示す。
class SampleClass<T>{
late final T value;
SampleClass(T arg){
value = arg;
}
}デザインパターンであるストラテジパターンにも応用することが出来る。
使用例
一番このジェネリクスが真価を発揮するのはDB操作の際である。
DB操作では、本来テーブルごとに操作するクラスを作成しなければいけないが、このジェネリクスを使用すると一つで十分となる。
以下にコード例を示す。
class RealmIOManager extends RealmIOManagerInterface {
final realmInsFac = RealmInstanceFactory();
final _reader = _DataReader();
final _adder = _DataAdder();
late Realm realm;
RealmIOManager(SchemaObject schemaObjectArg) {
realm = realmInsFac.createRealmIns(schemaObjectArg: schemaObjectArg);
}
@override
Future<void> add<T extends RealmValidatedSchemaValueInterface>(
{required RealmValidatedSchemaValueInterface dataInsToAddArg}) async {
_adder.add<T>(realm: realm, dataInsToAddArg: dataInsToAddArg);
}
@override
List<SCHEMA> readAll<SCHEMA extends RealmObject>() {
RealmIOResults results = _reader.readAll<SCHEMA>(realm: realm);
return results.payload;
}
@override
SCHEMA searchById<SCHEMA extends RealmObject>({required ObjectId idArg}) {
var result = _reader.searchById<SCHEMA>(realm: realm, idArg: idArg);
return result.payload;
}
@override
SCHEMA searchByName<SCHEMA extends RealmObject>({required ObjectId idArg}) {
var result = _reader.searchById<SCHEMA>(realm: realm, idArg: idArg);
return result.payload;
}
@override
void delete<SCHEMA extends RealmObject>({required ObjectId idArg}) {
var obj = searchById<SCHEMA>(idArg: idArg);
realm.write(() => realm.delete<SCHEMA>(obj));
}
@override
void deleteAll<SCHEMA extends RealmObject>() {
realm.write(() => realm.deleteAll<SCHEMA>());
}
}このコードではジェネリクスを使用してDB操作をクラス1つで完結させている。