我為我的資料庫 crud 操作設定了一組很好的通用函式。對于一些專門的功能,我需要更細粒度的控制。我希望能夠按屬性搜索資料庫物件串列。似乎不可能,有一個警告 - 所有物件都將具有 uuid 的屬性,這是我想要搜索的。太好了……用SO的一些天才頭腦一定是可能的。
當然,我想做這樣的事情:
Future<int> getExampleIndexByUUID({required String uuid}) async
=> await Hive.openBox<Example>('Example_Box')
.then((box) => box.values.toList().indexWhere(example)
=> example.uuid == uuid);
但是對于泛型型別,上述內容是不可能的:
Future<T> getExampleIndexByUUID<T>({
required T objectType,
required String uuid,
}) async => await Hive.openBox<T>(objectDatabaseNameGetter(objectType))
.then((box) => box.values.toList().indexWhere(example)
=> example... ); // Dead end- no property access here
PS我知道我可以在通用函式之外創建方法來處理這個問題。我還可以創建另一個大型開關盒來處理這個問題,但這是我想要避免的。我想學習在這種情況下更好地抽象我的代碼。任何幫助或指標表示贊賞!如果我唯一的選擇是擁有一個開關盒或在功能之外進行作業,那就這樣吧。
uj5u.com熱心網友回復:
定義一個通用介面。
最好的方法是讓所有具有
uuid屬性的類共享一個公共基類,然后您的泛型函式可以將其型別引數限制為該類的子型別:abstract class HasUuid { String get uuid; } class Example implements HasUuid { @override String uuid; Example(this.uuid); } Future<int> getExampleIndexByUUID<T extends HasUuid>({ required T objectType, required String uuid, }) async { var box = await Hive.openBox<T>(objectDatabaseNameGetter(objectType)); return box.values.toList().indexWhere( (example) => example.uuid == uuid), ); }使用回呼。
如果您不控制要使用的類,則可以讓泛型函式接受回呼來檢索所需的屬性。這對呼叫者來說會做更多的作業,但它也會更加靈活,因為呼叫者可以選擇訪問哪個屬性。
Future<int> getExampleIndexByUUID<T>({ required T objectType, required String Function(T) getUuid, required String uuid, }) async { var box = await Hive.openBox<T>(objectDatabaseNameGetter(objectType)); return box.values.toList().indexWhere( (example) => getUuid(example) == uuid), ); }您可以進一步概括:
Future<int> getExampleIndex<T, PropertyType>({ required T objectType, required PropertyType Function(T) getProperty, required PropertyType propertyValue, }) async { var box = await Hive.openBox<T>(objectDatabaseNameGetter(objectType)); return box.values.toList().indexWhere( (example) => getProperty(example) == propertyValue), ); }使用鴨式打字。
如果您可以保證所有提供的型別都有一個
uuid成員,另一種選擇是使用dynamic和鴨子型別(放棄靜態型別安全):Future<int> getExampleIndexByUUID<T>({ required T objectType, required String Function(T) getUuid, required String uuid, }) async { var box = await Hive.openBox<T>(objectDatabaseNameGetter(objectType)); return box.values.toList().indexWhere( (dynamic example) => example.uuid == uuid), ); }
順便說一句,混合async/await與Future.then. 只需使用async/ await。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/460178.html
