Dart为按值赋值语言,为什么对象赋值后修改会影响原对象?
Dart对象赋值时属性联动修改的原因
你对Dart「按值赋值」的认知存在一个常见的误区:Dart中所有变量存储的都是对象的引用,赋值操作传递的是引用的内存地址值,而非对象本身的深拷贝。
对应代码的执行逻辑拆解
你给出的代码执行过程分为以下几步:
class User{ int? id; String? name; int? age; User(this.id, this.name, this.age); } User user1 = User(1,'Harry', 21); User user2 = user1; user2.name = 'James'; print(user1.name); //prints out James print(user2.name); //prints out James
- 执行
User user1 = User(1,'Harry', 21);时,会在堆内存中创建一个User类的实例对象,user1变量存储的是这个实例在堆内存中的地址引用。 - 执行
User user2 = user1;时,是将user1中存储的地址引用拷贝一份赋值给user2,此时user1和user2指向堆内存中完全相同的同一个User实例。 - 执行
user2.name = 'James';时,是通过user2持有的引用,修改了堆内存中公共实例的name属性。 - 此时通过
user1的引用访问同一个实例的name属性,拿到的自然是修改后的值,所以两次打印结果都是James。
补充说明:为什么基础类型赋值不会出现这个现象
Dart中的num、bool、String等基础类型都是不可变对象,你无法修改这类对象本身的属性,每次赋值都是让变量指向一个新的对象:
int a = 1; int b = a; b = 2; print(a); // 输出1,print(b);输出2
上述代码中给b赋值2的操作,并不是修改原来的1这个对象,而是让b指向了新的2的内存地址,所以a不受影响,这也是很多人误以为Dart基础类型是值传递的原因,本质上它们的赋值逻辑和自定义对象是一致的,只是不可变的特性导致表现不同。
内容的提问来源于stack exchange,提问作者Thanoss
相关产品推荐
相关产品推荐

