VBS 中函数参数支持 ByVal 和 ByRef 两种传递方式,它们的区别是什么呢?

ByRef 表示传递的是指向对象的指针,函数体内修改变量值时将直接修改指针所指向的对象值,参数定义时如果没有声明为 ByVal 或 ByRef ,则默认为 ByRef ,例如:

msg = "DB MSG - Some junk from error message:SQL Err001"

Msgbox IsDBError(msg)

Msgbox msg

Function IsDBError(ByRef sMessage)

If inStr(sMessage, "DB") <= 0 Then

IsDBError = False

Exit Function

End If

sMessage = Replace(sMessage, "Some junk from error message:", "")

IsDBError = True

End Function

在这里调用 IsDBError 不仅返回布尔值,而且返回 ByRef 传递的修改后的变量值。

ByVal 表示传递的是对象的拷贝,函数体内修改的是局部变量的值。例如:

msg = "The field Value: abc"

Report msg

Msgbox msg

Function Report(ByVal Message)

Message = Replace(Message, "The field Value: ", "")

Msgbox (Message)

End Function

但是有个看起来像是例外的是 Dictionary ,例如下面的代码:

Sub AddValue(ByVal oDicationay)

oDicationay.Add "Some", "Thing"

End Sub

Set oDic = CreateObject("Scripting.Dictionary")

Call AddValue(oDic)

Msgbox oDic.Containes("Some") 'What will this print ,True or False?

按理, ByVal 是传递变量的拷贝,因此跳出 AddValue 函数体外之后应该取原来的变量值,但是这里脚本执行的结果是 True ,表明 AddValue 函数体内对变量值进行了直接的修改,其行为相当于 ByRef 。

原因是 oDic 对象并不是真正的 Dictionary 对象,而是指向 Dictionary 对象的指针,因此传递给 AddValue 的也不过是指针而已,最终修改的还是所指向的同一个 Dictionary 对象!

再来看下面的例子:

Sub DoIt(ByVal oDictionary)

oDictionary.Add "1", "1"

Set oDictionary = Nothing

End Sub

Sub DoIt2(ByRef oDictionary)

oDictionary.Add "2", "2"

Set oDictionary = Nothing

End Sub

Set oDic = CreateObject("Scripting.Dictionary")

Call DoIt(oDic)

MsgBox oDic.Count 'What will this print?

Call DoIt2(oDic)

MsgBox oDic.Count 'What will this print?

两个 Sub 中都用了 Set oDictionary = Nothing ,但是由于 ByVal 和 ByRef 的不同而产生不一样的结果:

第一个 Sub 中, ByVal 传递的是指向 oDic 对象的指针拷贝,因此设置为 Nothing 释放的是 oDictionary ,而不是 oDic ,因此 MsgBox 能显示 oDic 的 Count 属性值。

而第二个 Sub 中, ByRef 传递的是指向 oDic 对象的指针,因此设置为 Nothing 释放的就是 oDic 本身,因此后面的 MsgBox 尝试显示已被销毁的 oDic 对象的属性值时发生错误:缺少对象‘ oDic ’ !

ByRef vs. ByVal相关推荐

  1. 写给初学者:VB 中 ByRef 与 ByVal 参数传递方式的区别

    简而言之,ByRef 和 ByVal 的区别在于参数源是否可以被函数修改,前者(默认方式)是可以被修改的,而后者是不能被修改的. 例: Private Function Func(ByRef argv ...

  2. byref和byval区别的正确理解

    byref和byval其实按照字面上的理解来说,一个按照地址传递或者说指针,一个按照值传递,两个区别是什么呢,大众理解就是,按地址理解就是直接把它地址传进来,对形参的操作将影响实参.而按值传递就是co ...

  3. byref与byval的区别

    首先解释一下什么是实参,什么是形参 过程中的参数列表叫做形参 . 调用过程时的参数列表就实参. 形参与实参的类型必须一致. 调用时将实参的值传递给形参. Private sub command1_cl ...

  4. ByRef和ByVal

    PK ByRef:     我们常说的传地址,也就是用一旦在使用过程中改变了引用的数值,那么原数值做相应的改变.可以说ByRef用的随波逐流. ByVal:     所谓的传值:无论在使用过程中如何操 ...

  5. VBScript的中ByRef和ByVal的不同

    在VBScipt中ByRef表示的是地址的变化,而ByVal表示的是值得变化,比如 Dim i,j i=1 j=1 Function ByRefValue(ByRef val1) val1=val1+ ...

  6. byref和byval什么时候该使用什么时候不该使用

    214/01/16 1.按值传递 byval 即复制值,在过程内修改参数的值将不影响原来的变量; 2.按地址传递 byref 则相当于给变量取个别名,在过程内修改参数的值将影响原来的变量: 3.以表达 ...

  7. vbs过程参数--byref和byval

    vbs过程参数--byref(默认)和byval 请看例子: On error resume NextSub A1(byval s)s = s & "125" End Su ...

  8. Byval 和 ByRef 使用

    Byval 和 ByRef 使用 byval 单单传参数. byref 如果定义了一个参数指向它,他会那值传回来. 说得不是很清楚! 在 Visual Basic 中,可以通过分别指定关键字 ByVa ...

  9. 以下是一个使用 VBA 的例子,演示了 ByVal 和 ByRef 的区别,以及如何在函数中传递参数和返回值。

    以下是一个使用 VBA 的例子,演示了 ByVal 和 ByRef 的区别,以及如何在函数中传递参数和返回值: Sub Example()Dim x As Integer, y As Integerx ...

最新文章

  1. js ScripX插件打印
  2. 如何使用第三方域名解析
  3. python3进行汉字和unicode码的转换
  4. java向量数组异常,数组中空异常指针的Java错误处理
  5. CentOS 更改MySQL数据库目录位置
  6. Windows破解逆向-CrackMe_1实例(使用IDA Pro修改静态区资源)
  7. 利用Python来玩扫雷,极致的思维体验
  8. 【JAVA】Eclipse保存时出现“Save could not be completed”问题
  9. Extjs 4 MVC中全局配置文件
  10. 李彦宏开年内部信:2018营收破千亿,做出好产品的百度已归来
  11. 深度学习之---yolo源代码部分分析
  12. android opencv 图像旋转90度,使用OpenCV转换图像( 旋转 90度)的简单方法?
  13. 信息系统开发平台OpenExpressApp - 从compositewpf到MEF
  14. php导出excel出现乱码,完美解决phpexcel导出到xls文件出现乱码的问题
  15. 华东理工大学计算机图形答案,华东理工大学信息科学与工程学院硕士研究生导师张静...
  16. 制作简单的个人Logo
  17. ADB连接手机做淘宝猫币任务领取猫币
  18. 最新人脸识别技术方案
  19. 计算机网络——第二章(应用层)
  20. CubeMX STM32串口1DMA使用IDLE中断接收、串口2DMA接收DMX512信号(标准)

热门文章

  1. ThinkPad 声卡出现未安装任何音频输出设备
  2. 面向对象课程设计日志(八)
  3. 购房贷款 等额本息 等额本金
  4. matlab画图双坐标轴和多坐标轴代码
  5. css 属性 calc 的使用
  6. jme-再现虎式坦克
  7. Python中单引号,双引号,3个引号的用法
  8. IOT-OS之RT-Thread(六)--- 线程间同步与线程间通信
  9. 中国的漫威,还很遥远么
  10. 笔记|统计学习方法:感知机模型