为什么变量 A 没有被复制到变量 B?

Why variable A is not being copied to variable B?

我正在使用两个具有相同值的变量。变量 A 是一个初始变量,变量 B 是我用来应用更改的变量,所以当我想重置变量 B 时,我只是将 A 分配给它,问题是每次我这样做时,B 的更改都会应用于两者.我看了很多地方,这些是我尝试过的解决方案:

  1. List.toList()

    _fields!.clear();
    _fields = _initFields!.toList();
    
  2. 展开运算符 (...)

    _fields!.clear();
    _fields = [...?_initFields];
    

还尝试了下面的 post:Dart/Flutter – How to clone/copy a list

var newNumbers = List.from(numbers);
var newNumbers = List.generate(numbers.length, (index) => numbers[index]);
var newNumbers = List.of(numbers);
var newNumbers = List.unmodifiable(numbers);

这里是完整的代码:

import 'package:project/utilities/classes/filter_field.dart';

class FilterLogic {

  List<FilterField>? _initFields = [];
  List<FilterField>? _fields = [];
  bool? listComplete = false;

  void addField(FilterField? field) {

      _fields!.add(field!);

  }

  void addInitField(FilterField? field) {

    _initFields!.add(field!);

  }

  List<FilterField>? getFields() {

    return _fields;

  }

  void resetFieldsToOriginal() {

    _fields!.clear();
    _fields = [...?_initFields!];

  }

  void showFields() {

    print('_fields --------------------------------------------------------------------------------------');

    _fields!.forEach((element) {
      if(element.checked == true) {
        print({ element.checked, element.field, element.filteredApplied, element.criteria, element.filteringOperators});
      }
    });

    print('_initFields --------------------------------------------------------------------------------------');

    _initFields!.forEach((element) {
      if(element.checked == true) {
        print({ element.checked, element.field, element.filteredApplied, element.criteria, element.filteringOperators});
      }
    });

  }

}

以下是我如何填充两个变量:

filterCol.forEach((column) {
  String? filteredApplied;
  String? filteredCriteria = 'None';
  bool checked = false;

  filtersList.forEach((element) {
    if (column.field == element.field) {
      filteredApplied = element.operator;
      filteredCriteria = element.criteria;
      checked = true;
    }
  });

    FilterField field = FilterField(
      filteredApplied: filteredApplied,
      field: column.field,
      label: column.label,
      filteringOperators: column.filteringOperators,
      criteria: filteredCriteria,
      checked: checked == true ? true : false,
    );

  FilterField initField = FilterField(
    filteredApplied: filteredApplied,
    field: column.field,
    label: column.label,
    filteringOperators: column.filteringOperators,
    criteria: filteredCriteria,
    checked: checked == true ? true : false,
  );

  setState(() {

    filterLogic.addField(field);
    filterLogic.addInitField(initField);

  });
  
});

在这里我调用了重置方法:

DialogButton(
  width: 106.25,
  child: Text(
    "CANCEL",
    style: TextStyle(
        color: Colors.white, fontSize: 14, fontFamily: 'Chivo'),
  ),
  onPressed: () => {
    Navigator.of(context).pop(),
    setState(() {
    filterLogic.resetFieldsToOriginal();  // <-------------
  })
  },
  color: Color.fromRGBO(84, 84, 84, 1),
  radius: BorderRadius.circular(0.0),
),

仅仅复制列表是不够的,因为您的新列表引用了相同的 FilterField 实例。这意味着如果您更改新列表中的任何 FilterField,旧列表中也会有相同的更改。所以在你的情况下,你需要做一个所谓的 deep 克隆。您可以为此创建一个方法:

class FilterField {
   // ... other code
   FilterField CopyWith() {
      return new FilterField(...);
   }
}

然后你可以这样:

var newList = oldList.toList().map((item) => item.CopyWith()).toList();

现在您可以单独更改列表了。

但请注意,如果 FilterField 有任何其他需要更改的 类 实例,您也需要为这些实例创建新实例。这就是为什么它被称为深度克隆。

希望这就是您要找的。