#dart #generics
Вопрос:
У меня есть эти занятия
class CustomPopupAction<T> extends CustomAction {
final Icon icon;
final List<CustomPopupActionItem<T>> actions;
final void Function(T) onActionSelected;
CustomPopupAction({
required this.icon,
required this.actions,
required this.onActionSelected,
});
}
class CustomPopupActionItem<T> {
final T value;
final Widget Function(T) itemBuilder;
CustomPopupActionItem({
required this.value,
required this.itemBuilder,
});
}
и я пытаюсь создать меню переполнения, которое будет работать следующим образом:
- если кнопка видна, я создам
PopupMenuButton
- если кнопка переполнена, я создам
ListTile
, которая откроет диалоговое окно - он может содержать несколько различных типов, таких как
CustomAction
,CustomPopupAction<Locale>
,CustomPopupAction<String>
…
Я строю этот ряд вот так
if (a is CustomPopupAction) {
return PopupMenuButton(
icon: a.icon,
onSelected: (i) => a.onActionSelected(i),
itemBuilder: (context) {
return a.actions.map((i) => PopupMenuItem(
value: i.value,
child: i.itemBuilder(i.value),
)).toList();
},
);
} else {
return IconButton(...);
}
и, наконец, мой основной код:
...
return OverflowMenu(
actions: [
CustomPopupAction<Locale>(
icon: Icon(Icons.translate),
actions: [
CustomPopupActionItem<Locale>(
value: Locale('en'),
itemBuilder: (l) => ListTile(title: Text(l.toString()),
),
],
onActionSelected: (l) => print(l),
],
);
Но это не работает для меня, я получаю исключение Expected a value of type '(dynamic) => Widget', but got one of type '(Locale) => ListTile'.
Я знаю, что это потому if (a is CustomPopupAction)
, что на самом деле становится CustomPopupAction<dynamic>
.
- могу ли я каким-то образом убедить Dart, что
a
nas не динамический тип и что он должен работать с реальным типом? - если нет, то почему я получаю это исключение?
Locale
может быть присвоеноdynamic
переменной иListTile
явно является aWidget
. - могу ли я сделать это, вообще не проходя через динамику?
Комментарии:
1. Когда ты это делаешь
a is CustomPopupAction
, ты действительно делаешьa is CustomPopupAction<dynamic>
. Если условие верно,a
следовательно, будет повышено доCustomPopupAction<dynamic>
. Если вы хотите избежатьdynamic
этого , вам нужно будет указать явный параметр типа. Если вы не знаете этот тип статически , то это по своей сути означает, что вам потребуется выполнить дополнительные проверки типов во время выполнения .2. Спасибо, я так и думал. Какие проверки типа времени выполнения вы имеете в виду? Например, проверьте точный тип, например
CustomPopupAction<Locale>
? Это будет много проверок. Также разве вы не знаете, почему я получаю это исключение, когда эти типы (Locale -> динамический, ListTile ->> Виджет) должны быть совместимы?