我正面临着VBScript中的一些奇怪的事情。当我编写一个通过引用传递参数的过程时,调用这个过程的方式改变了传递参数的方式!
下面是一个示例:
Sub IncrementByRef(ByRef Value)
Value = Value + 1
End Sub
Sub IncrementByVal(ByVal Value)
Value = Value + 1
End Sub
Dim Num
Num = 10
WScript.Echo "Num : " & Num
IncrementByRef(Num) : WScript.Echo "IncrementByRef(Num) : " & Num
IncrementByRef Num : WScript.Echo "IncrementByRef Num : " & Num
IncrementByVal(Num) : WScript.Echo "IncrementByVal(Num) : " & Num
IncrementByVal Num : WScript.Echo "IncrementByVal Num : " & Num下面是输出:
U:\>cscript //nologo byrefbyval.vbs
Num : 10
IncrementByRef(Num) : 10
IncrementByRef Num : 11
IncrementByVal(Num) : 11
IncrementByVal Num : 11
U:\>当指定将参数传递给ByVal时,无论调用过程的方式如何,它都会按预期工作。但是,当指定将参数传递给ByRef时,如果以这种方式调用过程,它将按预期工作:
IncrementByRef Num但不是这样的:
IncrementByRef(Num)这对我来说很奇怪。有没有一种方法可以确保传递的参数是ByRef的,而不管这个过程是如何调用的?
发布于 2009-10-08 14:28:24
Eric Lippert有一篇关于在VBScript中使用括号的很好的文章:What do you mean "cannot use parentheses?"你的例子说明了他提到的一个要点,即:将一个ByRef参数放在括号中,将它作为ByVal传递。
简而言之,VBScript子例程调用中的括号不仅可以放在参数列表中,还可以放在各个参数周围(在这种情况下,它们被强制为ByVal)。如果使用了Call关键字,VBScript只需要将参数列表括在圆括号中。由于IncrementByRef(Num)调用不使用Call关键字,因此VBScript将括号视为应用于子例程参数,因此将其传递给ByVal而不是ByRef。
令人困惑,但这就是它的工作方式。
发布于 2009-10-08 13:41:21
这是一个特性,而不是一个bug:
http://msdn.microsoft.com/en-us/library/ee478101.aspx
如果参数包含在圆括号中,并且括号不适用于参数列表,则通过值传递ByRef参数。
如果满足以下条件之一,则括号将应用于参数列表:
因此,请尝试使用Call关键字或让它返回值。
发布于 2009-10-09 00:33:22
说清楚点。括号有三种不同的用途。
定义或调用
有两种方法可以将过程作为语句或表达式调用。
表达式:-
x = func(y)声明:-
func y注意:Call关键字调用该过程,就好像它是表达式的一部分,因此参数列表必须包含在括号中。
在上面,y本身代表了一个非常简单的表达式。在这一点上,我们完全可以使用y + z。实际上,此时我们可以使用任何有效的表达式,包括使用圆括号运算符的表达式。例如:
x = (y)是有效的表达式。因此,当你这样做的时候:
func(y)VBScript看到对func的调用,表达式(y)的结果将被传递给该调用。现在,即使func将该参数定义为ByRef,y中的值也不会受到影响,因为y实际上并没有作为参数传递。传递的是表达式(y)的结果,它将被临时存储在某个地方。即使这个临时存储被func修改,它也会在以后被丢弃,因此在参数被标记为ByVal的情况下也会有相同的行为。
https://stackoverflow.com/questions/1537819
复制相似问题