Dart类中列表属性修改元素时为何调用getter而非setter?
Dart中修改列表元素为何触发Getter而非Setter?
我定义了如下抽象类GetData,通过get和set关键字声明了多个公共属性,修改这些属性时会将_toUpdate设为true并更新对应的私有属性:
abstract class GetData{ // The data static List<double>? _settingsDefaultSchedule; static int? _settingsScheduleInAdvance; static int? _settingsPostoneDuration; static PlanData? _planData; static int? _homePageNumOfHours; static List<TaskData>? _savedTasks; // A variable that controls the updating of the data static bool _toUpdate = false; // Getter for the instance variables static List<double> get settingsDefaultSchedule => _settingsDefaultSchedule!; static int get settingsScheduleInAdvance => _settingsScheduleInAdvance!; static int get settingsPostoneDuration => _settingsPostoneDuration!; static PlanData get planData => _planData!; static int get homePageNumOfHours => _homePageNumOfHours!; static List<TaskData> get savedTasks => _savedTasks!; // Setters for the instance variables static set settingsDefaultSchedule(List<double> value) { if (_settingsDefaultSchedule == null || value != _settingsDefaultSchedule){ _toUpdate = true; _settingsDefaultSchedule = value; } } static set settingsScheduleInAdvance(int value) { if (_settingsScheduleInAdvance == null || value != _settingsScheduleInAdvance){ _toUpdate = true; _settingsScheduleInAdvance = value; } } static set settingsPostoneDuration(int value) { if (_settingsPostoneDuration == null || value != _settingsPostoneDuration){ _toUpdate = true; _settingsPostoneDuration = value; } } static set planData(PlanData value) { if (_planData == null || value != _planData){ _toUpdate = true; _planData = value; } } static set homePageNumOfHours(int value) { if (_homePageNumOfHours == null || value != _homePageNumOfHours){ _toUpdate = true; _homePageNumOfHours = value; } } static set savedTasks(List<TaskData> value) { if (_savedTasks == null || value != _savedTasks){ _toUpdate = true; _savedTasks = value; } } // ... }
其中savedTasks是列表类型,当我通过如下代码修改它的某个元素时,_toUpdate仍为false,调试发现Dart调用的是savedTasks的getter而非setter:
GetData.savedTasks[index] = TaskData( name: GetData.savedTasks[index].name, duration: GetData.savedTasks[index].duration, importance: newListIndex, key: GetData.savedTasks[index].key, everydayTask: GetData.savedTasks[index].everydayTask, everydayTaskTime: GetData.savedTasks[index].everydayTaskTime, oneTimeTask: GetData.savedTasks[index].oneTimeTask, );
我知道可以通过替换整个列表解决该问题,但想了解为何修改列表元素时会调用getter而非setter?
原因解析
- Getter返回的是列表对象的引用:调用
GetData.savedTasks时,getter只是返回私有变量_savedTasks指向的列表对象的引用,这个过程没有改变savedTasks属性本身的指向,自然不会触发setter。 - 修改列表元素是对象内部操作:
savedTasks[index] = ...本质是对getter返回的列表对象进行内部修改——仅改变了列表中某个索引的元素,并没有替换整个列表对象。此时savedTasks属性依然指向原来的列表,不符合setter的触发条件(给属性赋新的对象引用)。 - Setter仅在属性被重新赋值时触发:你的setter逻辑只有当给
savedTasks赋一个全新的列表对象(比如GetData.savedTasks = List.from(GetData.savedTasks)..[index] = newTask)时才会执行,因为这时候才改变了savedTasks属性的引用指向。
内容的提问来源于stack exchange,提问作者AdamMazur
相关产品推荐
相关产品推荐

