培训
调用过程时,提供的每个实参都对应于过程中定义的某个形参。 在某些情况下,过程代码可以更改调用代码中参数的基础值。 在其他情况下,过程只能更改参数的本地副本。
调用过程时,Visual Basic 会为通过 ByVal 传递的每个参数创建一个本地副本。 对于通过 ByRef 传递的每个参数,Visual Basic 将为过程代码提供对调用代码中参数的基础编程元素的直接引用。
如果调用代码中的基础元素是可修改的元素并且参数通过 ByRef
传递,则过程代码可以使用直接引用更改调用代码中该元素的值。
在过程声明中,为对应于实参的形参指定 ByRef。
在调用代码中,将可修改的编程元素作为参数传递。
在调用代码中,不要将参数括在参数列表中的括号中。
在过程代码中,使用参数名称为调用代码中的基础元素赋值。
请参阅下面示例中的演示。
如果调用代码中的基础元素是不可修改的元素,或者如果参数通过 ByVal
传递,则过程将无法更改其在调用代码中的值。 但是,该过程可以更改此类参数的本地副本。
在过程声明中,为对应于实参的形参指定 ByVal。
-或-
在调用代码中,将参数括在参数列表中的括号中。 这会强制 Visual Basic 通过值传递实参,即使相应的形参指定了
ByRef
也是如此。在过程代码中,使用形参名称为实参的本地副本赋值。 调用代码中的基础值保持不变。
下面的示例演示两个过程,这两个过程采用数组变量并对其元素进行操作。 increase
过程只向每个元素添加一个数组变量。 replace
过程将新数组分配给参数 a()
,然后向每个元素添加一个数组。
Public Sub increase(ByVal a() As Long)
For j As Integer = 0 To UBound(a)
a(j) = a(j) + 1
Next j
End Sub
Public Sub replace(ByRef a() As Long)
Dim k() As Long = {100, 200, 300}
a = k
For j As Integer = 0 To UBound(a)
a(j) = a(j) + 1
Next j
End Sub
Dim n() As Long = {10, 20, 30, 40}
Call increase(n)
MsgBox("After increase(n): " & CStr(n(0)) & ", " &
CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))
Call replace(n)
MsgBox("After replace(n): " & CStr(n(0)) & ", " &
CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))
第一个 MsgBox
调用显示“After increase(n): 11, 21, 31, 41”。 由于数组 n
是引用类型,因此 replace
可以更改其成员,即使传递机制为 ByVal
也是如此。
第二个 MsgBox
调用显示“After replace(n): 101, 201, 301”。 由于 n
通过 ByRef
传递,因此 replace
可以修改调用代码中的变量 n
并为其分配一个新的数组。 由于 n
是一个引用类型,因此 replace
还可以更改其成员。
可以防止过程在调用代码中修改变量本身。 请参阅如何:防止过程参数的值被更改。
通过引用传递变量时,必须使用 ByRef
关键字来指定此机制。
Visual Basic 中的默认值是按值传递参数。 但是,良好的编程做法是在每个声明的参数中包含 ByVal 或 ByRef 关键字。 这使得你的代码易于阅读。
允许过程更改调用代码中参数的基础值始终存在潜在风险。 请确保希望更改此值,并准备好在使用之前检查其有效性。