我在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
Run Code Online (Sandbox Code Playgroud)
这是输出:
U:\>cscript //nologo byrefbyval.vbs
Num : 10
IncrementByRef(Num) : 10
IncrementByRef Num : 11
IncrementByVal(Num) : 11
IncrementByVal Num : 11
U:\>
Run Code Online (Sandbox Code Playgroud)
当指定参数传递ByVal时,无论调用过程的方式如何,它都按预期工作.但是当指定参数传递ByRef时,如果以这种方式调用过程,它将按预期工作:
IncrementByRef Num
Run Code Online (Sandbox Code Playgroud)
但不是这样的:
IncrementByRef(Num)
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎很奇怪.有没有办法确保参数是通过ByRef传递的,无论程序是如何调用的?
Hel*_*len 40
Eric Lippert有一篇关于在VBScript中使用括号的好文章:
你的意思是"不能使用括号?" 你的例子说明了他提到的一个要点,即:ByRef
用括号括起一个参数将其传递给ByVal
.
简而言之,VBScript子例程调用中的括号不仅可以放在参数列表周围,还可以放在各个参数周围(在这种情况下它们是强制的ByVal
).并且VBScript只希望如果使用Call
关键字,则将参数列表括在括号中.由于IncrementByRef(Num)
调用不使用Call
关键字,因此VBScript将括号视为应用于子例程参数,因此将其传递ByVal
而不是ByRef
.
令人困惑,但这就是它的工作方式.
Joe*_*orn 19
这是一个功能,而不是一个错误:http:
//msdn.microsoft.com/en-us/library/ee478101.aspx
如果参数括在括号中且括号不适用于参数列表,则ByRef参数按值传递.
如果满足下列条件之一,则括号将应用于参数列表:
该语句是一个函数调用,具有对返回值的赋值.
该语句使用Call关键字.(Call关键字可以选择用于子程序调用,或者用于没有赋值的函数调用.)
因此,请尝试使用Call关键字或让它返回一个值.
要清楚.括号有三个不同的目的.
有两种方法可以将过程作为语句或表达式来调用.
表达:-
x = func(y)
Run Code Online (Sandbox Code Playgroud)
声明:-
func y
Run Code Online (Sandbox Code Playgroud)
请注意,Call
关键字调用过程就好像它是表达式的一部分,因此参数列表必须包含在parantheses中.
在上面,这y
本身代表了一个非常简单的尝试.我们现在可以使用y + z
了.实际上我们可以使用任何有效的表达式,包括使用括号运算符的表达式.例如:-
x = (y)
Run Code Online (Sandbox Code Playgroud)
是一个有效的表达.因此,当你这样做: -
func(y)
Run Code Online (Sandbox Code Playgroud)
VBScript看到对func
表达式结果(y)
传递的调用.现在,即使func
将此参数定义为ByRef
值,y
也不会受到影响,因为y
实际上并未将其作为参数传递.传递的是表达式的结果(y)
,它将存储在某个临时的地方.即使这个临时存储被修改func
它也会在之后被丢弃,因此在标记参数时具有相同的行为ByVal
.
归档时间: |
|
查看次数: |
38791 次 |
最近记录: |