You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 23:20:38