"var"和"out"参数之间有什么区别?

Rob*_*edy 56 delphi parameters pass-by-reference

声明的参数与var声明的参数之间的区别是什么out?编译器如何区别对待它们(例如,通过生成不同的代码,或通过更改它发出的诊断)?或者,不同的修饰符是否只允许程序员记录参数的预期用途?做了什么样的影响类型的参数对此事?

Mas*_*ler 46

一个var参数将通过引用传递,这就是它.

一个out参数,也是按引用传递,但它假定输入值是不相关的.对于托管类型(字符串,接口等),编译器将通过在例程开始之前清除变量来强制执行此操作,相当于写入param := nil.对于非托管类型,编译器实现out相同的var.

需要注意的是有管理的参数的结算是在调用点进行,因此对于函数生成的代码不改变outvar参数.

  • @Rob 我认为塞尔格在这里有点困惑。他在他的博客上说得对:http://sergworks.wordpress.com/2012/10/01/a-word-about-out-parameters-in-delphi/ (2认同)
  • @Serg,如果其他语言*在分配之前没有*清除输出参数,并且Delphi在调用之前没有清除*,那就是内存泄漏.Delphi不知道被调用函数会做什么,所以唯一安全的选择是在将变量传递给其他代码之前始终清除变量.最好清除变量两次而不是完全没有. (2认同)

NGL*_*GLN 8

对于编译器来说没有太大的区别.看梅森的答案.

在语义上,有一个很大的区别:

  • var告诉程序员该例程可以使用其当前值,
  • out告诉程序员该例程将忽略/丢弃其当前值.

  • @David,这个答案是处理文档,而不是实际行为.我想大多数人一般都认为*Delphi中的`out`与C#中的`out`的工作方式相同,在编写参数之前读取参数是非法的.当人们在Delphi中声明`out`参数时,我认为通常他们打算如何对待它们.使用`out`而不是`var`用于*记录*意图,即使编译器实际上没有强制执行它.在写入之前读取`out`参数是一个错误和错误,即使编译器没有将其标记为错误. (8认同)
  • @NGLN我完全明白了.我完全理解out的语义.只是因为编译器没有强制执行它,函数可以很好地使用我输入的值.换句话说,例程的作者可以欺骗我,编译器不会抱怨.想象一下,如果编译器没有打扰强制类型安全.只是因为函数说它希望接收一种类型的参数,错误的程序员可以发送其他东西. (2认同)
  • 我认为,如果程序员使用"out",那么他宣称他不会读取该值并认为它是有用的.我个人只检查是否有人在我遇到问题时正确编写了例行程序.所以我认为NGLN的答案是正确的. (2认同)