作为可选参数传递以使子例程像被省略一样工作的优雅方法?
Elegant way to pass as an optional parameter to make the subroutine work as if it was omitted?
在VB6中,函数Mid(string, start, [length])
有一个可选参数length
。如果省略,将传递 start
边界后的整个字符。
假设我只希望在特定条件下使用此默认行为:
s = Mid(s, i, IIf(condition, j, TheValue)) ' What could be TheValue?
由于length
是Variant
类型,所以我试了Empty
。它没有用。 -1
和 Nothing
也没有。
我不想在 If-Then-Else
子句或其他方式中复制到 Mid 调用。这可能吗?
在 c++ 中,std::string 这些可选参数在默认效果为零位置或长度时用 0 表示,在“无限”长度时用 std::string::npos 表示。您可以显式提供该值并获得相同的行为。
我不知道 m/s 字符串中的等价常量是什么[实际上它是一个不同的函数定义,所以没有]。另一种方法是传入字符串长度,因为这是当前可能的最长长度。
?: 三元运算符是一种呈现 2 个值的简单方法,并且可以在它们之间进行选择。
您可以定义自己的 Mid 函数:
Public Function Mid(p_sString As String, p_iStart As Integer, Optional p_iLength As Integer = -1) As String
If p_iLength < 0 Then
Mid = VBA.Mid(p_sString, p_iStart)
Else
Mid = VBA.Mid(p_sString, p_iStart, p_iLength)
End If
End Function
这应该适用于您问题中的代码,使用 -1
(或任何负整数)作为 TheValue
。
不存在这样的值。当您省略长度参数时,编译器会通过 VBRT 选择不同的路径——它会生成不同的代码。如果你想模仿它,你需要做同样的事情,使用 If-Else
或类似的结构来处理这两种情况,比如@ÉtienneLaneville suggests
作为@Étienne 解决方案的替代方案,VB 提供了 IsMissing
方法:
Public Function Mid(p_sString As String, p_iStart As Integer, Optional p_iLength As Integer) As String
If IsMissing(p_iLength) Then
Mid = VBA.Mid(p_sString, p_iStart)
Else
Mid = VBA.Mid(p_sString, p_iStart, p_iLength)
End If
End Function
作为这个包装方法 returns 一个字符串,我建议使用 Mid
的 String
版本,即 Mid$
。后者比 Variant
版本 (Mid)
稍快
这在 this site 中得到了很好的解释,但在发帖时,请求超时。不确定是永远消失了还是只是暂时的问题。
这是 OP 的 s = Mid(s, i, IIf(condition, j, TheValue))
行
的工作示例
Option Explicit
Property Get TheValue(Optional RetVal As Variant)
TheValue = RetVal
End Property
Private Sub Form_Load()
Dim s As String
Dim i As Long
Dim j As Long
Dim condition As Boolean
s = "test test test"
i = 6: j = 3
condition = False
s = Mid(s, i, IIf(condition, j, TheValue)) '<--- this works!
Debug.Print s
End Sub
请注意 TheValue
returns 如何“缺失”Variant
即 IsMissing
测试呈阳性并且可以用来代替可选参数而不是不传递实参.
在VB6中,函数Mid(string, start, [length])
有一个可选参数length
。如果省略,将传递 start
边界后的整个字符。
假设我只希望在特定条件下使用此默认行为:
s = Mid(s, i, IIf(condition, j, TheValue)) ' What could be TheValue?
由于length
是Variant
类型,所以我试了Empty
。它没有用。 -1
和 Nothing
也没有。
我不想在 If-Then-Else
子句或其他方式中复制到 Mid 调用。这可能吗?
在 c++ 中,std::string 这些可选参数在默认效果为零位置或长度时用 0 表示,在“无限”长度时用 std::string::npos 表示。您可以显式提供该值并获得相同的行为。
我不知道 m/s 字符串中的等价常量是什么[实际上它是一个不同的函数定义,所以没有]。另一种方法是传入字符串长度,因为这是当前可能的最长长度。
?: 三元运算符是一种呈现 2 个值的简单方法,并且可以在它们之间进行选择。
您可以定义自己的 Mid 函数:
Public Function Mid(p_sString As String, p_iStart As Integer, Optional p_iLength As Integer = -1) As String
If p_iLength < 0 Then
Mid = VBA.Mid(p_sString, p_iStart)
Else
Mid = VBA.Mid(p_sString, p_iStart, p_iLength)
End If
End Function
这应该适用于您问题中的代码,使用 -1
(或任何负整数)作为 TheValue
。
不存在这样的值。当您省略长度参数时,编译器会通过 VBRT 选择不同的路径——它会生成不同的代码。如果你想模仿它,你需要做同样的事情,使用 If-Else
或类似的结构来处理这两种情况,比如@ÉtienneLaneville suggests
作为@Étienne 解决方案的替代方案,VB 提供了 IsMissing
方法:
Public Function Mid(p_sString As String, p_iStart As Integer, Optional p_iLength As Integer) As String
If IsMissing(p_iLength) Then
Mid = VBA.Mid(p_sString, p_iStart)
Else
Mid = VBA.Mid(p_sString, p_iStart, p_iLength)
End If
End Function
作为这个包装方法 returns 一个字符串,我建议使用 Mid
的 String
版本,即 Mid$
。后者比 Variant
版本 (Mid)
这在 this site 中得到了很好的解释,但在发帖时,请求超时。不确定是永远消失了还是只是暂时的问题。
这是 OP 的 s = Mid(s, i, IIf(condition, j, TheValue))
行
Option Explicit
Property Get TheValue(Optional RetVal As Variant)
TheValue = RetVal
End Property
Private Sub Form_Load()
Dim s As String
Dim i As Long
Dim j As Long
Dim condition As Boolean
s = "test test test"
i = 6: j = 3
condition = False
s = Mid(s, i, IIf(condition, j, TheValue)) '<--- this works!
Debug.Print s
End Sub
请注意 TheValue
returns 如何“缺失”Variant
即 IsMissing
测试呈阳性并且可以用来代替可选参数而不是不传递实参.