我想我最近(终于)开始了解ByVal和ByRef在VBA中的工作方式。
观察
在我迄今所读过的所有教程和引用中,ByRef总是“传递对象”,ByVal是“传递对象的副本”。对我来说,后者意味着对象在内存中的位置被复制,指向新位置的指针被返回。现在我意识到,情况并不总是如此,事实上,据我所知,很少是这样的:相反,大多数对象和类实际上都是通过ByRef传递的,即使在例程的签名中指定了ByVal。
System.Collections.ArrayList以静默方式传递ByRef,如以下代码所示:
Sub test()
Dim list1 As Object, list2 As Object
Set list1 = CreateObject("System.Collections.ArrayList")
list1.Add "foo"
Set list2 = RemoveItem(list1)
Debug.Assert list2.Contains("foo") = False 'as expected
Debug.Assert list1.Contains("foo") = True 'raises error, meaning list1 was passed byref not byval
End Sub
Function RemoveItem(ByVal list As Object) As Object 'ByVal
list.Remove "foo" 'expect to remove from a copy and return that
Set RemoveItem = list
End Function考虑到我对ByVal的了解,这让我感到惊讶。进一步的深入研究表明,要想从ByVal中获得一个我想要的副本,我需要传递的对象有一个方法来实现这个功能。对于ArrayList,.Clone方法创建一个浅拷贝。所以我的职能是:
Function RemoveItem(ByRef list As Object) As Object 'ByRef or ByVal, makes no difference
Dim listCopy As Object
Set listCopy = list.Clone 'make a shallow copy of the object
listCopy.Remove "foo" 'actually remove from a copy and return that
Set RemoveItem = listCopy
End FunctionVB Array在传递ByVal时会引发编译器错误,这可能是对此的警告
问题
所有这些让我思考:
ByVal和ByRef有什么区别(如果有的话)?Boolean、Long)与不能传递ByVal的类和类型区分开来VB6 编写的东西。ByVal响应的对象?ByVal,并返回其本身的.Clone。ByVal的,其他对象如何模仿这种行为(同样,在Python中,一切都是对象,所以所有的行为都可以被复制*)。还是我不用担心这种事的发生?
- Is it possible to mimic an `Array`'s behaviour and raise a compiler error when passed `ByVal` - as an array has no clone method and cannot be readily copied so is always `ByRef`
*轶事,我对Python很陌生
发布于 2018-04-15 19:04:53
在我迄今所读过的所有教程和引用中,ByRef总是“传递对象”,ByVal是“传递对象的副本”。
你有上面的例子的链接吗?
ByVal类似于*foo,而ByRef类似于**foo。ByVal类似于bar,而ByRef类似于*bar。ByRef还是ByVal。Long是32位整数,实际上Boolean也是,但只能接受两个值中的一个(0=False、-1=True)。您不必担心,VBA以安全的名义设置限制。
- If you want to enforce passing `ByRef` for your objects then create a Type instead of a class.
=就可以复制类型。数组和类型被传递给ByRef,因为它们是在堆栈上创建的。
发布于 2018-04-15 19:06:17
对于VBA中的对象和类,在传递byval或byref方面没有真正的区别。传递byref意味着指针被传递'byref',对象保持不变。
如果您想一想,它对于(Excel)对象来说是有意义的;无论您是通过Range("A1") byref还是byval,它仍然是我们正在寻址的相同的单元格。
https://stackoverflow.com/questions/49845406
复制相似问题