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

如何从旧变量赋值新变量,修改新变量时不改变原变量?(Dart)

解决Dart中对象赋值后修改属性影响原对象的问题

你的问题本质是Dart中引用类型的赋值逻辑:当你执行final Student newStudent = student;时,并没有创建新的Student实例,只是把原对象的引用赋值给了newStudent——两者指向内存中同一个对象,所以修改newStudent的属性自然会同步到原student上。

要让原对象保持不变,你需要创建原对象的独立副本,以下是几种常用方案:

方案1:添加拷贝构造函数

在Student类中定义一个拷贝构造函数,通过原对象的属性值创建新实例:

class Student {
  String? name;
  int? age;

  // 普通构造函数
  Student(this.name, this.age);
  // 拷贝构造函数
  Student.copy(Student other) : name = other.name, age = other.age;

  @override
  String toString() => '$name, $age';
}

使用时通过拷贝构造函数创建新对象:

void main() {
  final Student student = Student('Lincoln', 29);
  print('Student before $student');

  // 通过拷贝构造函数创建独立副本
  final Student newStudent = Student.copy(student);
  newStudent?.name = 'Abraham';
  print('new Student $newStudent'); // 'Abraham', 29
  print('Student after $student'); // 'Lincoln', 29
}

方案2:实现clone方法

在类中添加一个clone方法,返回新的实例:

class Student {
  String? name;
  int? age;

  Student(this.name, this.age);

  // 克隆方法
  Student clone() {
    return Student(name, age);
  }

  @override
  String toString() => '$name, $age';
}

使用时调用clone方法:

void main() {
  final Student student = Student('Lincoln', 29);
  print('Student before $student');

  final Student newStudent = student.clone();
  newStudent?.name = 'Abraham';
  print('new Student $newStudent'); // 'Abraham', 29
  print('Student after $student'); // 'Lincoln', 29
}

方案3:使用不可变类(推荐)

将类的属性设为final,使其成为不可变类——如果需要修改属性,必须返回一个新的实例。这种方式更符合Dart的最佳实践,避免意外的副作用:

class Student {
  final String? name;
  final int? age;

  Student(this.name, this.age);

  // 用于修改属性并返回新对象的方法
  Student copyWith({String? name, int? age}) {
    return Student(
      name ?? this.name,
      age ?? this.age,
    );
  }

  @override
  String toString() => '$name, $age';
}

使用时通过copyWith方法创建修改后的新对象:

void main() {
  final Student student = Student('Lincoln', 29);
  print('Student before $student');

  // 通过copyWith创建新对象,原对象不受影响
  final Student newStudent = student.copyWith(name: 'Abraham');
  print('new Student $newStudent'); // 'Abraham', 29
  print('Student after $student'); // 'Lincoln', 29
}

内容的提问来源于stack exchange,提问作者Septian Dika

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 21:20:26