Dart中List与int的传递机制疑问:是否分别为按引用传递与按值传递?
关于Dart中List和int的参数传递问题拆解
嘿,这个问题刚好戳中了很多刚接触Dart的开发者容易混淆的点——先直接给你澄清:Dart里所有参数传递都是按值传递,但因为不同数据类型的特性,看起来像是有“按引用传递”和“按值传递”的区别,咱们结合你的代码一步步说清楚。
先看List的例子
你的代码片段:
void main() { var foo = ['a','b']; var bar = foo; bar.add('c'); print(foo); // [a, b, c] print(bar); // [a, b, c] }
这里的逻辑是:
foo是一个引用变量,它存储的不是整个List的内容,而是这个List对象在内存中的地址。- 当你执行
var bar = foo时,其实是把foo里存储的那个地址值复制了一份给bar。现在foo和bar都指向同一个List对象。 - 所以用
bar.add('c')修改的是这个共享的List对象的内部状态,自然foo也能看到变化。这不是“按引用传递”,而是传递的是引用的值,两个变量共享同一个对象实例而已。
再看int的例子
对应的代码:
var a = 3; int b = a; b += 2; print(a); // 3 print(b); // 5
这里的核心是:
int是Dart中的不可变值类型,变量a直接存储的就是数值3,而不是某个对象的地址。- 当你执行
int b = a时,是把a里的数值3完整复制了一份给b,此时a和b是完全独立的两个变量,各自存储3。 - 之后
b += 2的操作,其实是创建了一个新的int对象(值为5),然后让b指向这个新对象,而a仍然指向原来的3,所以两者互不影响。
哪些类型会有类似“引用”或“值”的表现?
- 类似“引用传递”效果的类型:所有可变的对象类型,比如
List、Map、自定义的类实例等。这类变量存储的是对象的引用,赋值或传参时复制的是引用值,多个变量指向同一个对象,修改对象内部状态会影响所有指向它的变量。 - 类似“值传递”效果的类型:所有不可变的值类型,比如
int、double、String、bool、num等。这类变量直接存储值本身,赋值时复制整个值,修改其中一个不会影响另一个。(比如String也是不可变的,你执行var s1 = 'hi'; var s2 = s1; s2 += ' there';,s1还是'hi',s2会变成'hi there'——因为s2指向了新创建的字符串对象)
一个关键误区纠正
很多人会把“传递引用的值”和真正的“按引用传递”搞混。真正的按引用传递允许你修改传入变量的指向,但Dart做不到这点。比如下面的例子:
void changeList(List<String> list) { // 让函数内的list变量指向一个全新的List对象 list = ['x', 'y']; } void main() { var myList = ['a', 'b']; changeList(myList); print(myList); // 输出还是['a','b'] }
如果Dart是按引用传递,外部的myList应该会变成['x','y'],但实际并没有——因为函数内的list是外部myList的引用值的副本,修改它的指向不会影响外部变量。这就彻底证明了Dart是按值传递的。
内容的提问来源于stack exchange,提问作者fendy3d
相关产品推荐
相关产品推荐

