一般分为值传递和引用传递,大部分语言都是这样吧。 有没有特殊的语言,只有值传递的?
1
geelaw 2023-08-19 13:13:37 +08:00 via iPhone
Java 和 C 都只能传值。
|
2
geelaw 2023-08-19 13:27:20 +08:00
另外,JavaScript 也只有传值。
对于纯函数式语言来说,传引用和传值没有任何区别。 |
3
justonelastdance OP @geelaw js 有引用传递吧。传对象和数组就是引用传递
|
4
geelaw 2023-08-19 14:02:57 +08:00
@justonelastdance #3 一个方法的一个参数是传引用 (pass by reference) 的含义是:实参可以被赋值,且方法内对形参的赋值会导致对实参赋值。
let a = {}; function b(c) { c.d = 1; c = null; } b(a); console.log(a); 这里 a 不是 {} 那个对象,而是对象引用,a 的值引用了那个对象。b(a) 这个调用中: 形参 c 的值是实参 a 的值的副本,故一开始 c 也引用了那个对象,透过 c 的值可以操作那个对象,因此 c.d = 1 这句话会改变那个对象,当然,这没有改变 a ,因为 a 不是那个对象,而 a 还是引用了那个对象。 形参 c 和实参 a 绑定到了不同的存储位置,对 c 的赋值并不影响 a 的值(也就是不影响 a 的值引用了哪个对象),因此 c 是传值。 最简单的理解 JavaScript 的方法是这样的:这个世界上有两种值,对象实例、对象引用,除了 import 带来的,其他所有变量名都指示互不相同的存储位置,且每个具名的存储位置都只能存储对象引用。( 123 这种 typeof 会得到 'number' 的东西直接理解为不可变对象就好,不要搞什么 primitive value 之说。) |
5
justonelastdance OP @geelaw 这个是引用传递,因为 a 和 c 都指向了同一个引用,c 改变了引用的值,a 的值也跟着变了
|
6
geelaw 2023-08-19 15:38:03 +08:00 via iPhone
@justonelastdance #5
a 的值没有变,在 b 退出之前 c 的值是 null ,但 b 退出之后 a 不是 null 。 另外“a 和 c 都指向同一个引用”是错误的。a 和 c 代表了不同的存储位置,并且进入 b 的时候 a 和 c 所代表的存储位置具有相同的值,这两个相同的值都是对象引用。 |
7
justonelastdance OP @geelaw a 的值如果不变的话打印出的应该是{},实际打印出的是{d: 1},因为引用改变了值。后面 c=null 是把 c 指向了另一个引用所以不会造成 a 也是 null
|
8
geelaw 2023-08-19 17:01:54 +08:00 1
另外,Python 也只有传值,最早的 FORTRAN 只有传引用。
@justonelastdance #7 您需要复习 JavaScript 基础知识,a 的值是指向那个对象实例的引用,而不是那个对象实例。在 b 的调用中,通过 c (也是指向那个对象的引用)改变了对象实例,当然可以通过 a 看见。 你当然理解这里发生了什么,但是你的术语用法和计算机科学中的主流用法不符。我暂时找不到教科书,而且我上面的说明已经很明确了,你也可以参考 https://stackoverflow.com/a/7744623/4598348 |
9
Ericcccccccc 2023-08-19 17:19:09 +08:00
都是值传递, 你以为的引用传递是传递了地址值.
|
10
leonshaw 2023-08-19 17:54:19 +08:00 via Android
大部分都是传值,印象里也就 C++, rust 这种有引用传递。简单的区分方法是看函数里 param = xxxx 和函数外 arg = xxxx 是不是同样的效果。
|
11
lance6716 2023-08-19 18:04:08 +08:00 via Android
@justonelastdance 可以理解为,“引用”指的是 a 这个 name 和 c 这个 name 是同一个东西,对 c “本身”的改变会影响到 a 。而不是他们是两个东西但是具有相同的值且值是一个指针,并通过 .d 影响了同一对象
|
12
Rache1 2023-08-19 18:16:37 +08:00
在看到楼上的回复之前,我都以为在 JavaScript 这种,传一个对象进去,然后再方法内部可以改变对象本身成员的值的情况,对于对象就是按引用传递的,而对于标量这种则是按值传递,函数内部对其的赋值不能改变其外部。我想楼主之前也是这样想的。🫥
刚刚去查了一下相关资料,没想到 “传递对象,函数内部改变对象成员值” 的情况也叫按值传递。而按引用传递的就是说在函数内可以直接改变源数据。 受教 💕 |
13
agagega 2023-08-19 19:34:14 +08:00 via iPhone 1
C/C++传参的模型看起来难,但是最灵活和最能帮助理解的
|
14
netabare 2023-08-20 03:15:55 +08:00 via Android 1
call by name/call by value 算不算特殊的传参方式?(虽然其实应该是运算策略来着。。
|