最近看到有人面试的时候被问到了 “Dart中函数调用是值传递还是引用传递?”
初看感觉跟Java应该是相同的,结果搜索到的链接里面言之凿凿的说是传值操作,顿时感觉有些迷茫。
针对大对象,如果进行拷贝传值,会诱发大量的内存复制操作,这种情况是不可想象的。而基本类型,比如整数,字符,传递地址又是得不偿失的性能损失,明明通过寄存器就可以直接传递参数,却非要从内存中读取一遍,是完全没有必要的。
Dart中,基本数据类型传值,类传引用
类对象传值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
main(){ Test a = new Test(5); print("a的初始值为:${a.value}"); setValue(a); print("修改后a的值为: ${a.value}"); } class Test{ int value = 1; Test(int newValue){ this.value = newValue; } } setValue(Test s){ print("修改value为100"); s.value = 100; } |
输出结果为:
1 2 3 |
a的初始值为:5 修改value为100 修改后a的值为:100 |
基本类型传值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
main(){ int s = 6; setValue(s); print(s); //输出6,而不是7 } class Test{ int value = 1; Test(int newValue){ this.value = newValue; } } setValue(int s){ s += 1; } |
上面的代码,其实转换成 Java 也是一样的结果。
但是深入思考,在 Flutter 中,上面的结论并不全面,对于异构模型而言,取决于内存架构。
如果是非一致内存架构,则CPU跟GPU之间只能进行拷贝操作。
即使是一致内存架构,也分为物理一致还是软件一致,如果仅仅是软件一致,比如PCIE独立显卡,依旧是只能进行拷贝操作,当然拷贝是显卡驱动完成的。只有物理,驱动都完全支持的情况下,才会出现物理意义上的引用传值的情况。有时候,即是两者都支持,GPU对虚拟内存的支持也是一个决定因素。
还是蛮复杂的。