我有以下 Dart 代码
void main() {
final filters = [
FilterOption(
label: 'Category',
hint: 'All categories',
items: A.values,
onChange: (_) => print('Not implemented yet'),
itemLabeler: (item) => item.toString().toUpperCase()
),
FilterOption(
label: 'Time',
hint: 'All time',
items: B.values,
onChange: (_) => print('Not implemented yet'),
itemLabeler: (item) => item.toString().toLowerCase()
)
];
try {
filters.first.itemLabeler;
} catch(e) {
print(e);
}
print('Program terminated');
}
enum A {
here, are, some, options
}
enum B {
here, are, another, few, options
}
class FilterOption<T> {
final String label;
final String hint;
final List<T> items;
final void Function(T item) onChange;
final String Function(T item) itemLabeler;
const FilterOption({
required this.label,
required this.hint,
required this.items,
required this.onChange,
required this.itemLabeler
});
}
这是 DartPad 上的输出
TypeError: Instance of '(A) => String': type '(A) => String' is not a subtype of type '(_Enum) => String'
Program terminated
我知道 StackOverflow 上有类似的问题,但是,许多人要么没有问题的答案,要么建议在列表之外实施。我希望能够将任意数量的 FilterOptions 发送到某个 UI 元素来显示。我还希望泛型类型是任何数据类型,而不仅仅是枚举。我怎么解决这个问题?感谢任何可以提供任何见解或解决方案的人。
假设过滤器不仅仅存在于枚举上,并且没有通用的超类型,那么您可以尝试一些方法。
首先,您可以在使用之前先尝试投射
FilterOption
。
void main() {
final filters = [
FilterOption(
label: 'Category',
hint: 'All categories',
items: A.values,
onChange: (_) => print('Not implemented yet'),
itemLabeler: (item) => item.toString().toUpperCase(),
),
FilterOption(
label: 'Time',
hint: 'All time',
items: B.values,
onChange: (_) => print('Not implemented yet'),
itemLabeler: (item) => item.toString().toLowerCase(),
),
];
try {
(filters.first as FilterOption<A>).itemLabeler;
} catch (e) {
print(e);
}
print('Program terminated');
}
enum A { here, are, some, options }
enum B { here, are, another, few, options }
class FilterOption<T> {
final String label;
final String hint;
final List<T> items;
final void Function(T item) onChange;
final String Function(T item) itemLabeler;
const FilterOption({
required this.label,
required this.hint,
required this.items,
required this.onChange,
required this.itemLabeler
});
}
其次,可以尝试将回调函数包装在方法调用中:
void main() {
final filters = [
FilterOption(
label: 'Category',
hint: 'All categories',
items: A.values,
onChange: (_) => print('Not implemented yet'),
itemLabeler: (item) => item.toString().toUpperCase(),
),
FilterOption(
label: 'Time',
hint: 'All time',
items: B.values,
onChange: (_) => print('Not implemented yet'),
itemLabeler: (item) => item.toString().toLowerCase(),
),
];
try {
filters.first.itemLabeler;
} catch (e) {
print(e);
}
print('Program terminated');
}
enum A { here, are, some, options }
enum B { here, are, another, few, options }
class FilterOption<T> {
final String label;
final String hint;
final List<T> items;
final void Function(T item) _onChange;
final String Function(T item) _itemLabeler;
void onChange(T item) => _onChange(item);
String itemLabeler(T item) => _itemLabeler(item);
const FilterOption({
required this.label,
required this.hint,
required this.items,
required void Function(T item) onChange,
required String Function(T item) itemLabeler,
}) : _onChange = onChange,
_itemLabeler = itemLabeler;
}