首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >VBScript中的ByRef和ByVal

VBScript中的ByRef和ByVal
EN

Stack Overflow用户
提问于 2009-10-08 13:33:18
回答 6查看 43K关注 0票数 33

我正面临着VBScript中的一些奇怪的事情。当我编写一个通过引用传递参数的过程时,调用这个过程的方式改变了传递参数的方式!

下面是一个示例:

代码语言:javascript
复制
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

下面是输出:

代码语言:javascript
复制
U:\>cscript //nologo byrefbyval.vbs
Num : 10
IncrementByRef(Num) : 10
IncrementByRef Num : 11
IncrementByVal(Num) : 11
IncrementByVal Num : 11

U:\>

当指定将参数传递给ByVal时,无论调用过程的方式如何,它都会按预期工作。但是,当指定将参数传递给ByRef时,如果以这种方式调用过程,它将按预期工作:

代码语言:javascript
复制
IncrementByRef Num

但不是这样的:

代码语言:javascript
复制
IncrementByRef(Num)

这对我来说很奇怪。有没有一种方法可以确保传递的参数是ByRef的,而不管这个过程是如何调用的?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 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

令人困惑,但这就是它的工作方式。

票数 43
EN

Stack Overflow用户

发布于 2009-10-08 13:41:21

这是一个特性,而不是一个bug:

http://msdn.microsoft.com/en-us/library/ee478101.aspx

如果参数包含在圆括号中,并且括号不适用于参数列表,则通过值传递ByRef参数。

如果满足以下条件之一,则括号将应用于参数列表:

  • 该语句是对返回值进行赋值的函数调用。

  • 语句使用Call关键字。( call关键字可以选择性地用于子例程调用,或用于没有赋值的函数调用。)

因此,请尝试使用Call关键字或让它返回值。

票数 19
EN

Stack Overflow用户

发布于 2009-10-09 00:33:22

说清楚点。括号有三种不同的用途。

定义或调用

  1. 以指示数组上的索引器时,用于括起参数列表。
  2. 作为表达式中的运算符。

有两种方法可以将过程作为语句或表达式调用。

表达式:-

代码语言:javascript
复制
x = func(y)

声明:-

代码语言:javascript
复制
func y

注意:Call关键字调用该过程,就好像它是表达式的一部分,因此参数列表必须包含在括号中。

在上面,y本身代表了一个非常简单的表达式。在这一点上,我们完全可以使用y + z。实际上,此时我们可以使用任何有效的表达式,包括使用圆括号运算符的表达式。例如:

代码语言:javascript
复制
 x = (y)

是有效的表达式。因此,当你这样做的时候:

代码语言:javascript
复制
 func(y)

VBScript看到对func的调用,表达式(y)的结果将被传递给该调用。现在,即使func将该参数定义为ByRefy中的值也不会受到影响,因为y实际上并没有作为参数传递。传递的是表达式(y)的结果,它将被临时存储在某个地方。即使这个临时存储被func修改,它也会在以后被丢弃,因此在参数被标记为ByVal的情况下也会有相同的行为。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1537819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档