我真的很想知道,通过引用传递(或传递指针)在语义上是否是“最佳”解决方案?特别是对于原始类型,感觉就像:
int x = 5;
x = foo(x);
比自然
int x = 5;
foo(x);
我首先想到了需要返回错误代码的代码,但是后来我意识到使用异常机制总是(?)比这更可取。是否有真正的理由希望通过引用传递?- 暂时不考虑速度。
我真的很想知道,通过引用传递(或传递指针)在语义上是否是“最佳”解决方案?特别是对于原始类型,感觉就像:
int x = 5;
x = foo(x);
比自然
int x = 5;
foo(x);
我首先想到了需要返回错误代码的代码,但是后来我意识到使用异常机制总是(?)比这更可取。是否有真正的理由希望通过引用传递?- 暂时不考虑速度。
可以说,对于原始类型,按值传递它们确实更自然。只看数学,我们都对值有了解,并且知道将值映射到其他值是什么意思。
例如,当我们编写 时sin(x)
,我们真的希望我们的函数sin
将值 (of) 映射x
到我们简单表示的另一个值sin(x)
。有时我们想给映射的值一个不同的名字,所以我们可以写一些类似的东西y := sin(x)
并使用y
而不是sin(x)
.
现在,如果sin
通过引用获取此参数,sin(x)
则意味着 的值x
将被映射到sin(x)
并再次隐式存储x
- 因此旧的值x
将丢失!
在许多情况下,这真的很烦人,因为我们可能想再次使用“旧” x
——所以我们必须事先复制它的值。
现在让我们看看另一方面:OOP。在那里你想要有对象,例如汽车,并且这个对象应该能够改变。例如,汽车可以移动(如果有汽油),因此它们可以改变位置;开车会消耗汽油,因此油箱会随着时间的推移而耗尽;你可以打开门等...
在这里,我们不会考虑将一辆车映射到另一辆车(副本),车门打开或油箱略微减少,但我们真正考虑的是同一辆车,但现在车门打开。
简而言之:
当我们希望参数不失去其原始含义时,按值传递是好的——它对于映射值最有用。
当我们希望我们的值(我们在这里解释为一个对象)改变时,通过引用传递是好的。
因此,从语义上讲,您通常希望使用按值传递/按引用传递是很清楚的,但是按值传递可能会遇到一些问题:
如果您的对象是一个资源,那么按值传递该资源将(可能)意味着您将分配第二个资源!这有时根本不可能——例如考虑(TCP)网络连接。当您已经拥有一个时,不可能在同一个端口上打开另一个,在已经打开的连接中共享上下文。所以在这种情况下,你真的别无选择,只能通过引用传递你的网络连接(套接字、数据流等)。