可选参数的默认值必须是常量
Posted
技术标签:
【中文标题】可选参数的默认值必须是常量【英文标题】:The default value of an optional parameter must be constant 【发布时间】:2020-09-09 09:48:24 【问题描述】:所以我创建了这个事件跟踪器应用程序,我有两个屏幕,分别是地图和事件列表。 我正在尝试使位置列表与我在应用程序状态中的位置相同。请记住,placeList 是一个可修改的列表,我需要将地点添加到此列表中。
但是,每当我初始化 this.places=PlaceMapState.placeList
时,我都会收到“”,并且我无法将其更改为常量,因为我需要它来更新 PlaceMapState 类中的位置列表,并且我无法从 AppState 中删除它,因为我在 PlaceList 类中使用它来获取位置作为列表。
我也不想完全删除 AppState,因为它还包含地图。
请问有什么解决办法吗???
这是我使用此列表的班级:
class AppState
AppState(
this.places = PlaceMapState.placeList, //// here is the problem!!!!!!!!!!!!!!!!!!!
this.selectedCategory = PlaceCategory.events,
this.viewType = PlaceTrackerViewType.map,
) : //assert(places != null),
assert(selectedCategory != null);
List<Place> places;
PlaceCategory selectedCategory;
PlaceTrackerViewType viewType;
AppState copyWith(
List<Place> places,
PlaceCategory selectedCategory,
PlaceTrackerViewType viewType,
)
return AppState(
selectedCategory: selectedCategory ?? this.selectedCategory,
viewType: viewType ?? this.viewType,
);
static AppState of(BuildContext context) => AppModel.of<AppState>(context);
static void update(BuildContext context, AppState newState)
AppModel.update<AppState>(context, newState);
static void updateWith(
BuildContext context,
List<Place> places,
PlaceCategory selectedCategory,
PlaceTrackerViewType viewType,
)
update(
context,
AppState.of(context).copyWith(
places: places,
selectedCategory: selectedCategory,
viewType: viewType,
),
);
@override
bool operator ==(Object other)
if (identical(this, other)) return true;
if (other.runtimeType != runtimeType) return false;
return other is AppState &&
other.places == places &&
other.selectedCategory == selectedCategory &&
other.viewType == viewType;
@override
int get hashCode => hashValues(places, selectedCategory, viewType);
这里是 placeList 类,我使用地点来获取列表:
class PlaceList extends StatefulWidget
const PlaceList(Key key) : super(key: key);
@override
PlaceListState createState() => PlaceListState();
class PlaceListState extends State<PlaceList>
ScrollController _scrollController = ScrollController();
void _onCategoryChanged(PlaceCategory newCategory)
_scrollController.jumpTo(0.0);
AppState.updateWith(context, selectedCategory: newCategory);
void _onPlaceChanged(Place value)
// Replace the place with the modified version.
final newPlaces = List<Place>.from(AppState.of(context).places);
final index = newPlaces.indexWhere((place) => place.id == value.id);
newPlaces[index] = value;
AppState.updateWith(context, places: newPlaces);
@override
Widget build(BuildContext context)
return Column(
children: <Widget>[
_ListCategoryButtonBar(
selectedCategory: AppState.of(context).selectedCategory,
onCategoryChanged: (value) => _onCategoryChanged(value),
),
Expanded(
child: ListView(
padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 8.0),
controller: _scrollController,
shrinkWrap: true,
children: AppState.of(context)
.places //this the places im talking about!!!!!!!!!!!!!!!!!
.where((place) =>
place.category == AppState.of(context).selectedCategory)
.map((place) => _PlaceListTile(
place: place,
onPlaceChanged: (value) => _onPlaceChanged(value),
))
.toList(),
),
),
],
);
【问题讨论】:
【参考方案1】:要求默认参数的常量值的常见解决方法是使用 sentinel 参数作为默认值,可以为const
。通常,该哨兵参数可以是null
:
class AppState
AppState(
List<Place>? places,
...
) : places = places ?? PlaceMapState.placeList;
List<Place> places;
...
【讨论】:
以上是关于可选参数的默认值必须是常量的主要内容,如果未能解决你的问题,请参考以下文章